본문 바로가기
JavaScript/Deep Dive

19 프로토타입 (2)

by lacuca9 2024. 9. 28.

instanceof 연산자

이항 연산자로서 좌변에 객체를 가리키는 식별자, 우변에 생성자 함수를 가리키는 식별자를 피연산자로 받음

우변의 피연산자가 함수가 아닌 경우 TypeError

객체 instanceof 생성자 함수

 

우변의 생성자 함수의 prototype에 바인딩된 객체가 좌변의 객체의 프로토타입 체인 상에 존재하면 true

그렇지 않으면 false로 평가 된다

 

// 생성자 함수
function Person(name) {
  this.name = name;
}
const me = new Person('Lee');
// 프로토타입으로 교체할 객체
const parent = {};
// 프로토타입의 교체
Object.setPrototypeOf(me, parent);
// Person 생성자 함수와 parent 객체는 연결되어 있지 않다.
console.log(Person.prototype === parent); // false
console.log(parent.constructor === Person); // false

// Person.prototype이 me 객체의 프로토타입 체인 상에 존재하지 않기 때문에 false로 평가된다.
console.log(me instanceof Person); // false
// Object.prototype이 me 객체의 프로토타입 체인 상에 존재하므로 true로 평가된다.
console.log(me instanceof Object); // true

 

프로토타이븨 constructor 프로퍼티가 가리키는 생성자 함수를 찾는게 아니라

생성자 함수의 prototype에 바인딩된 객체가 프로토타입 체인 상에 존재하는지 확인.

 

직접 상속

Object.create에 의한 직접 상속

명시적으로 프로토타입을 지정하여 새로운 객체를 생성한다.

첫 번째 매개변수에는 생성할 객체의 프로토타입으로 지정할 객체를 전달

두 번째 매개변수에는 생성할 객체의 프로퍼티 키와 프로퍼티 디스크립터 객체로 이뤄진 객체를 전달

객체를 생성하면서 직접적으로 상속을 구현하는 것

장점 :

  • new 연산자가 없이도 객체를 생성할 수 있다
  • 프로토타입을 지정하면서 객체를 생성할 수 있다
  • 객체 리터럴에 의해 생성된 객체도 상속받을 수 있다

 

객체 리터럴 내부에서 __proto__에 의한 지접 상속

const myProto = { x: 10 };
// 객체 리터럴에 의해 객체를 생성하면서 프로토타입을 지정하여 직접 상속받을 수 있다.
const obj = {
  y: 20,
  // 객체를 직접 상속받는다.
  // obj → myProto → Object.prototype → null
  __proto__: myProto
};
/* 위 코드는 아래와 동일하다.
const obj = Object.create(myProto, {
  y: { value: 20, writable: true, enumerable: true, configurable: true }
});
*/
console.log(obj.x, obj.y); // 10 20
console.log(Object.getPrototypeOf(obj) === myProto); // true

 

 

정적 프로퍼티/메서드

정적(static) 프로퍼티/메서드는 생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티/메서드.

// 생성자 함수
function Person(name) {
  this.name = name;
}
// 프로토타입 메서드
Person.prototype.sayHello = function () {
  console.log(`Hi! My name is ${this.name}`);
};
// 정적 프로퍼티
Person.staticProp = 'static prop';
// 정적 메서드
Person.staticMethod = function () {
  console.log('staticMethod');
};
const me = new Person('Lee');

// 생성자 함수에 추가한 정적 프로퍼티/메서드는 생성자 함수로 참조/호출한다.
Person.staticMethod(); // staticMethod
// 정적 프로퍼티/메서드는 생성자 함수가 생성한 인스턴스로 참조/호출할 수 없다.
// 인스턴스로 참조/호출할 수 있는 프로퍼티/메서드는 프로토타입 체인 상에 존재해야 한다.
me.staticMethod(); // TypeError: me.staticMethod is not a function

 

 

프로퍼티 존재 확인

in 연산자

객체 내에 특정 프로퍼티가 존재하는지 여부를 확인

// key: 프로퍼티 키를 나타내는 문자열
// object: 객체로 평가되는 표현식
key in object
const person = {
  name: 'Lee',
  address: 'Seoul'
};

// person 객체에 name 프로퍼티가 존재한다.
console.log('name' in person);    // true
// person 객체에 address 프로퍼티가 존재한다.
console.log('address' in person); // true
// person 객체에 age 프로퍼티가 존재하지 않는다.
console.log('age' in person);     // false

 

 

프로퍼티 열거

모든 프로퍼티를 순회하며 열거(enumeration)하려면 for...in문을 사용

Object.prototype의 프로퍼티가 열거되지 않는다.

[Enumerable]]이 false면 열거 불가 ( 열거 가능 여부를 나타내는 불리언 값)

const person = {
  name: 'Lee',
  address: 'Seoul'
};

// for...in 문의 변수 key에 person 객체의 프로퍼티 키가 할당된다.
for (const key in person) {
  console.log(key + ': ' + person[key]);
}
// name: Lee
// address: Seoul

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'JavaScript > Deep Dive' 카테고리의 다른 글

20 strict mode  (0) 2024.09.28
19 프로토타입 (1)  (1) 2024.09.26
18 함수와 일급 객체  (0) 2024.09.26
17 생성자 함수에 의한 객체 생성  (2) 2024.09.25
16 프로퍼티 어트리뷰트  (0) 2024.09.23