language/javaScript

6. JS 핵심 - 객체

wooweee 2023. 4. 20. 02:19
728x90

1. 객체 생성

  • 종류 2가지
    1. 빈 객체 생성한 후, 멤버(속성, 함수) 추가
    2. 객체의 생성과 동시에 멤버 추가
// 1. 객체의 생성방법
const person = {};
// property 추가
person.firstName = "join";

console.log(typeof person); // object

// 2. 객체 생성 + 초기화
const myObject = {
  firstName: "join",
};

console.log(typeof myObject); // object

 

2. 생성자로 객체 생성

  • 생성자를 정의하면 객체를 편리하게 생성
  • 해당 객체 호출시 객체 이름 { property, function} 출력
  • 하지만 type은 object
  • 주의
    • 생성자라고 해도 결국에는 function일 뿐이다.
    • 해당 function을 사용을 할 때 new를 사용하면 해당 function이 생성자로 작동을 하게 된다.
    • 그래서 function 중 생성자로 사용하고 싶은 것은 첫 char을 대문자로 작성을 한다. - 전통

 

  • this
    • 객체 내부 : 객체 자신
    • 해당 생성자로 생성한 객체는 주소를 가진다.
    • this는 해당 객체 주소이다.
// 생성자로 객체 생성
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 차이점
const myObject = { firstName: "join" };

console.log(myObject); // { firstName: 'join' }
console.log(typeof myObject); // object

const obj = new Person("a", 12);
console.log(obj); // Person { name: 'a', age: 12 } -- 앞에 Person이 붙음
console.log(typeof obj); // object

const obj2 = Person("a", 21); // window의 property가 된다.

 

  • 각 객체별로 모듈화가 되어있다. 서로 공유하지 않는다.

 

3. 객체의 속성(멤버) 삭제

  • delete연산자로 객체의 속성 삭제
  • 물려받은 속성은 삭제 불가
  • 생성자에 설정한 멤버 삭제 불가
  • 생성자를 이용해서 생성한 인스턴스의 멤버는 삭제 가능
function Person(name, age) {
  this.name = name;
  this.age = age;
}
const obj = new Person("a", 12); // Person { name: 'a', age: 12 }

// instance 멤버 삭제
delete obj.name;
console.log(obj.toString()); // name: undefined, age : 12

// 해당 class 멤버 삭제 시도
delete Person.name; // 생성자 속성 제거 불가
console.log(obj.toString()); // params에 name 유지되어있다.

 

4. instanceof

  • 기본형은 당연히 사용안됨
  • 객체일 때만 사용 가능
  • 생성자로 생성한 인스턴스는 해당 생성자 명의 객체 타입을 사용할 수 있다.

 

5. prototype, __proto__, constructor

 

deep dive 19단원 내용 추가

 

  • prototype
    • 함수 객체의 property 중 하나로, 해당 함수를 생성자로 사용하여 만든 객체들이 공통으로 사용할 수 있는 property와 메소드를 저장하는 객체
    • 생성자 함수를 정의할 때, 그 생성자로부터 만들어진 객체들이 공유할 property나 메소드를 추가하기 위한 용도로 사용
    • property와 메소드는 생성자 함수가 생성될 때마다 한 번만 생성되고, 이를 상속받은 객체들은 모두 이 property와 method를 사용할 수 있습니다.

 

  • __proto__는 모든 객체가 가지고 있는 숨겨진 property 중 하나
    • property는 객체가 생성될 때 해당 객체의 생성자 함수의 prototype을 참조
    • 즉, 객체가 생성된 후에 해당 객체와 생성자 함수의 prototype 사이에 연결을 만들어 준다. 따라서, __proto__를 이용해 상속을 구현할 수 있다.
    • 간단하게 말하면, prototype은 생성자 함수가 가지고 있는 객체이고, __proto__는 해당 객체가 가지고 있는 prototype 객체를 참조하는 property이다. prototype은 함수 객체에서만 사용되는 것이고, __proto__는 모든 객체에서 사용됩니다.

 

  • 생성자의 prototype을 이용한 함수 공유
function Person(name, age) {
  this.name = name;
  this.age = age;
}

var obj = new Person("david", 10);
var obj2 = new Person("wendy", 20);

// prototype function 생성
Person.prototype.getName = function () {
  return this.name;
};

// prototype property 생성
Person.prototype.abc = "123";

// prototype property 사용
console.log(obj.abc);
console.log(obj2.abc);

// prototype method 사용
console.log(obj.getName());
console.log(obj2.getName());
console.dir(Person); // prototype property 생성 - 내부에 __proto__, constructor 존재
console.dir(obj); // 내부에 __proto__ 존재

 

6. this

  • this는 기본적으로 함수를 호출하는 객체를 의미
  • 전역 범위에서 this는 window를 가리킨다.
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const obj = new Person("a", 12); // Person { name: 'a', age: 12 }
const obj2 = Person("b", 2); // new를 사용하지 않아서 window객체의 멤버로 들어간다.

const myObject = {
  firstName: "join",
};

// instanceof
// console.log(obj instanceof obj2); // error

console.log(obj instanceof Object); //true
console.log(obj instanceof Person); //true

console.log(obj2 instanceof Object); //false
console.log(obj2 instanceof Object); //false

console.log(myObject instanceof Person); //false
console.log(myObject instanceof Object); // true

 

  • person("b",2); 하면 window객체로 값이 들어가서 소스 살펴봤는데 Window객체가 존재하고 window객체가 또 존재
  • Window 와 window 의 차이점
    • Window는 브라우저에서 최상위 객체를 나타내며,
    • window는 브라우저에서 열린 각 창을 나타냅니다.
    • 브라우저 창이 여러 개 열리면 각 창은 자체적인 window 객체를 가지고 있고, 이 window 객체는 Window 객체를 상속 받는다.

 

6.1 call(), apply()로 this의 대상 변경

  • call(), apply(), bind()를 사용하면 this()가 가리키는 대상을 변경할 수 있다.
  • == 이미 생성된 객체에 적용 가능하다.
function Person(name, age) {
  this.name = name;
  this.age = age;
}

var p = new Person("tom", 33);
var p3 = {};
var p4 = new Object();

Person.call(p3, "a", 11);
Person.apply(p3, ["b", 0]);

console.log(p3);

 

6.2. 중첩된 함수에서의 this

  • 함수가 중첩되면, this의 의미가 달라진다.
  • 방법
    1. that = this
    2. bind()
    3. lambda식()
// 중첩된 함수에서의 this
function Person(name, age) {
  console.log(this); // person
  temp();
  function temp() {
    console.log(this); // window
  }
}

// that 이용
function Person(name, age) {
  console.log(this);
  const that = this; // that
  temp();
  function temp() {
    console.log(this); //window
    console.log();
    console.log(that); // person
  }
}

 

7. 객체의 속성에 접근제한

  • 생성자의 변수를 지역변수로 선언하여 접근을 제한
  • getter 사용
function Person(name, age) {
  // this는 곧 해당 function으로 객체를 만든 참조변수의 주소가 된다.
  this.name = name;
  this.age = age;
}

var p = new Person("a", 12); // this === p
console.log(p.name);
console.log(p.age);

// undefined 됨
function Person(name, age) {
  // this.name = name;
  // this.age = age;

  var name = name;
  var age = age;
}

var p = new Person("a", 12);
console.log(p.name);
console.log(p.age);

// getter로 내부 함수 가져오기
// function이면서 생성자가 될 수있다.

function Person(name, age) {
  var name = name;
  var age = age;

  this.getName = function () {
    return name;
  };

  this.getAge = function () {
    return age;
  };
}

var p = new Person("a", 12); // new를 통해서 해당 function을 생성자로 사용
console.log(p.getName());
console.log(p.getAge());

 

8. 두 객체간의 상속관계 맺어주기

  • JS 에선 상속관계를 맺는 것은 prototype과 __proto__의 연결을 해주는 과정이다
  • super() 역할을 하는 .call() 함수가 존재
// 상속 관계
function Person(name, age) {
  this.name = name;
  this.age = age;
}

function Manager(dept, name, age) {
  Person.call(this, name, age); // super()
  this.dept = dept;
}

const m = new Manager("sales", "woo", 12);
// super()를 이용해서 Person 생성자를 호출하지만 아직 상속관계를 맺진 않았다.
console.log(m.age); // 12
console.log(m instanceof Person); // false

// 상속관계 맺기
// manager 함수의 prototype 객체의 __proto__ 부분을 Person 함수의 prototype과 연결 시켜준다.
Manager.prototype.__proto__ = Person.prototype;

console.log(m instanceof Person); // 상속관계를 맺어서 true 반환