19장 프로토타입 (4)

Yuri Lee·2021년 5월 6일
0

19.11 직접 상속

19.11.1 Object.create에 의한 직접 상속

/**
* 지정된 프로토타입 및 프로퍼티를 갖는 새로운 객체를 생성하여 반환한다. 
* @param {Object} prototype - 생성할 객체의 프로토타입으로 지정할 객체
* @param {Object} [propertiesObject] - 생성할 객체의 프로퍼티를 갖는 객체
* @param {Object} 지정된 프로토타입 및 프로퍼티를 갖는 새로운 객체
*/
Object.creat(prototype[, propertiesObject])

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

  • Object.create 메서드는 첫 번째 매개변수에 전달한 객체의 프로토타입 체인에 속하는 객체를 생성한다.
  • 객체를 생성하면서 상속을 직접 구현한다.
  • ESLint 에서는 Object.prototype 의 빌트인 메서드를 객체가 직접 호출하는 것을 권장하지 않는다. Object.create 메서드를 통해 프로토타입 체인의 종점에 위치하는 객체를 생성할 수 있기 때문이다. 프로토타입 체인의 종점에 위치하는 객체는 Object.prototype의 빌트인 메서드를 사용할 수 없다.

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

  • Object.create 메서드에 의한 직접 상속은 장점이 있지만 두 번째 인자로 프로퍼티를 정의하는 것은 번거롭다.
  • 따라서 ES6에서는 객체 리터럴 내부에서 __proto__ 접근자 프로퍼티를 사용하여 직접 상속을 구현할 수 있다.
const myProto = { x : 10 };

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

19.12 정적 프로퍼티/메서드

  • 정적 프로퍼티/메서드는 생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티/메서드를 말한다.
  • 정적 프로퍼티/메서드는 생성자 함수가 생성한 인스턴스로 참조/호출할 수 없다.
  • 인스턴스의 프로토타입 체인에 속한 객체의 프로퍼티/메서드가 아니므로 인스턴스로 접근할 수 없다.
  • MDN 에서도 정적 프로퍼티/메서드와 프로토타입 프로퍼티.메서드를 구분하여 소개혹 있다.
    • 프로토타입 프로퍼티 메서드 표기 : prototype을 #으로 표기하기도 한다. (Object.prototype.isPrototypeOf = Object#isPrototypeOf)

19.13 프로퍼티 존재 확인

19.13.1 in 연산자

  • 객체 내에 특정 프로퍼티가 존재하는지 여부를 확인한다.
  • 확인 대상 객체의 프로퍼티 뿐만 아니라 확인 대상 객체가 상속받은 모든 프로토타입의 프로퍼티를 확인한다.
  • in 연산자 대신 ES6의 Reflect.has 메서드를 사용할 수도 있다.
/**
* key : 프로퍼티 키를 나타내는 문자열
* object : 객체로 평가되는 표현식
*/
key in object

19.13.2 Object.prototype.hasOwnProperty 메서드

  • 객체에 특정 프로퍼티가 존재하는지 확인할 수 있다.
  • 전달받은 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환, 상속받은 프로토타입의 프로퍼티 키인 경우 false를 반환한다.

19.14 프로퍼티 열거

19.14.1 for...in 문

  • 객체의 모든 프로퍼티를 순회하며 열거시킨다.
    • 열거 시 순서를 보장하지 않음. 주의!
  • 객체의 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티 중에서 프로퍼티 어트리뷰트 [[Enumberable]]의 값이 true인 프로퍼티를 순회하며 얼거한다.
  • 프로퍼티 키가 심벌인 프로퍼티는 열거하지 않는다.
  • 배열에는 for...in문을 사용하지 말고 for 문 혹은 for...of / Array.protoytpe.forEach 사용을 권장한다.
const person2 = {
    name: 'Lee',
    address: 'Seoul',
    __proto__ : { age: 20}
};

for (const key in person2) {
    console.log(key + ':' + person2[key]);
}

//name:Lee
//address:Seoul
//age:20
  • 객체 자신의 프로퍼티만 열거하려면 Object.prototype.hasOwnProperty 메서드를 사용하여 객체 자신의 프로퍼티인지 확인해야 한다.
for (const key in person2) {
  // 객체 자신의 프로퍼티인지 확인
    if (!person2.hasOwnProperty(key)) continue;
    console.log(key + ':' + person2[key]);
}

//name:Lee
//address:Seoul

19.14.2 Object.keys/values/entries 메서드

  • for...in 문은 객체 자신의 고유 프로퍼티 + 상속받은 프로퍼티도 열거한다. 따라서 Object.prototype.hasOwnProperty 메서드를 활용한 추가 작업이 필요하다.
  • 따라서 객체 자신의 열거 가능한 프로퍼티 키를 배열로 반환하는 Object.keys 메서드를 사용하는 것이 좋다.
onsole.log(Object.keys(person2));
// ["name", "address"]
  • ES8에서 도입한 Object.values 메서드는 객체 자신의 열거 가능한 프로퍼티 값을 배열로 반환함.
  • ES8에서 도입한 Object.entries 메서드는 객체 자신의 열거 가능한 프로퍼티 키와 값의 쌍의 배열을 배열에 담아 반환함.

🌳 느낀점

  • 드디어 프로토타입 마무리!

위 글은 위키북스의 모던 자바스크립트 Deep Dive 를 읽고 정리한 내용입니다.

profile
Step by step goes a long way ✨

0개의 댓글