티스토리 뷰
19.8 오버라이딩과 프로퍼티 섀도잉
프로토타입 프로퍼티: 프로토타입이 소유한 프로퍼티(+메서드)
인스턴스 프로퍼티: 인스턴스가 소유한 프로퍼티(+메서드)
프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면(오버라이딩) 인스턴스 프로퍼티로 추가됨
프로퍼티 섀도잉: 상속 관계에 의해 프로퍼티가 가려지는 현상
오버라이딩(overriding)
상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의하여 사용하는 방식
오버로딩(overloading)
동일한 이름의 함수를 매개변수의 타입 또는 개수로 메서드를 구별하여 호출하는 방식
자바스크립트는 지원하지 않지만 arguments 객체를 사용해 구현할 수 있음
하위 객체를 통해 프로토타입의 프로퍼티를 변경/삭제하는 것(set)은 불가능
19.9 프로토타입의 교체
1. 생성자 함수에 의한 프로토타입 교체
constructor 프로퍼티는 자바스크립트 엔진이 프로토타입을 생성할 때 암묵적으로 추가한 프로퍼티이기 때문에
프로토타입을 교체하면 constructor 프로퍼티와 생성자 함수 간의 연결이 파괴됨
-> 교체할 객체에 constructor 프로퍼티를 추가하여 프로토타입의 constructor 유지
const Person = (function () {
function Person(name) {
this.name = name;
}
Person.prototype = {
constructor: Person,
sayHello() {
console.log(`Hi! My name is ${this.name}`);
}
};
return Person;
}());
2. 인스턴스에 의한 프로토타입 교체
__proto__ 프로퍼티 혹은 Object.setPrototypeOf 메서드로 교체 가능
생성자 함수의 prototype 프로퍼티를 교체하는 것이 아닌 이미 만들어진 인스턴스의 프로퍼티를 교체하는 것
1.과 마찬가지로 constructor와 연결이 파괴됨
function Person (name) {
this.name = name;
}
const me = new Person('Lee');
const parent = {
constructor: Person,
sayHello() {
console.log(`Hi! My name is ${this.name}`);
}
};
Object.setPrototypeOf(me, parent);
console.log(Person.prototype === Object.getPrototypeOf(me)); // false;
Person.prototype = parent;
console.log(Person.prototype === Object.getPrototypeOf(me)); // true;
프로토타입 교체를 통해 객체 간의 상속 관계를 동적으로 변경하는 것은 번거로움. 19.11 직접 상속이 편하고 안전
그리고 그보다 25장 클래스를 사용하는 것이 더 간편하고 직관적임
19.10 instanceof 연산자
객체 instanceof 생성자 함수
우변이 함수가 아닌 경우 TypeError 발생
우변의 생성자 함수의 proptotype에 바인딩된 객체가 좌변 객체의 프로토타입 체인에 존재하는지를 불리언으로 리턴
프로토타입의 constructor 프로퍼티가 가리키는 생성자 함수와 비교하는 것이 아님
constructor와 생성자 함수와 연결이 파괴되어도 생성자 함수의 prototype 프로퍼티와 프로토타입 간 연결이 유지되어있다면 instanceof는 true 리턴
instanceof 연산자 함수 구현
function isInstanceof(instance, constructor) {
const prototype = Object.getPrototypeOf(instance);
if (prototype === null) return false;
return prototype === constructor.prototype || isInstanceof(prototype, constructor);
}
19.11 직접 상속
1. Object.create에 의한 직접 상속
Object.create는 명시적으로 프로토타입을 지정하여 새로운 객체를 생성
첫번째 인자: 프로토타입으로 지정할 객체
두번째 인자: 생성할 객체의 프로퍼티 키와 프로퍼티 디스크립터 객체로 이뤄진 객체
const obj = Object.create(Object.prototype, {
x: { value: 1, writable: true, enumerable: true, configurable: true }
});
- new 연산자 없이 객체 생성 가능(new Person('Lee'), Object.create(Person.prototype))
- 프로토타입을 지정하면서 객체 생성 가능
- 객체 리터럴에 의해 생성된 객체도 상속받을 수 있음(Object.create({x: 1})
프로토타입 체인의 종점에 위치하는 객체는 Object.prototype의 빌트인 메서드를 사용할 때 간접적으로 호출해야함
const obj = Object.create(null);
obj.a = 1;
console.log(Object.prototype.hasOwnProperty.call(obj, 'a')); // true
2. 객체 리터럴 내부에서 __proto__에 의한 직접 상속
ES6부터 객체 리터럴 내부에서 __proto__ 접근자 프로퍼티를 사용하여 직접 상속을 구현할 수 있음
const prototypeExample = { x: 10 };
const obj = {
y: 20,
__proto__: prototypeExample
};
console.log(obj.x, obj.y); // 10 20
console.log(obj); // { y: 20 }
console.log(Object.getPrototypeOf(obj) === prototypeExample); // true
19.12 정적 프로퍼티/메서드
생성자 함수 객체가 소유한 프로퍼티/메서드
인스턴스에서 참조/호출할 수 없음
ex. Object.create({})
인스턴스/프로토타입 메서드 내에서 this를 사용하지 않는다면 그 메서드는 정적 메서드로 변경할 수 있음
=> 인스턴스를 생성하지 않아도 호출할 수 있음
메서드 표기시 prototype 대신 #으로 표기하기도 함
Object.prototype.isPrototypeOf = Object#isPrototypeOf
19.13 프로퍼티 존재 확인
1. in 연산자
객체 내에 특정 프로퍼티가 존재하는지 boolean 리턴
주의: 상속받은 모든 프로토타입의 프로퍼티를 확인
키 in 객체
Reflect.has(대상 객체, 키)
=> 동일하게 동작
2. Object.prototype.hasOwnProperty 메서드
전달받은 키가 객체 고유의 프로퍼티인지 boolean 리턴
19.14 프로퍼티 열거
1. for ... in 문
for (변수선언문 in 객체) {...}
모든 프로퍼티를 순회하며 열거.
상속받은 프로퍼티 포함. 프로퍼티 어트리뷰트 [[Enumerable]] 값이 true인 프로퍼티를 순회하며 열거
- Object.prototype 제외([[Enumerable]]이 false이기 때문)
- 프로퍼티 키가 심벌인 프로퍼티는 열거하지 않음
순서를 보장하지 않음(모던 브라우저는 순서 보장, 숫자-실제로는 문자-인 프로퍼티 키는 정렬하여 열거)
변수에 key 할당
객체 고유의 프로퍼티만 열거하려면 Object.prototype.hasOwnProperty 메서드를 사용하여 확인하는 작업 필요
배열도 사실 객체이기 때문에 프로퍼티와 상속받은 프로퍼티가 열거될 수 있음
-> for ... in 문보다 for 반복문, for ... of 문(변수에 value 할당), Array.prototype.forEach 메서드 사용을 권장
2. Object.keys/values/entries 메서드
객체 고유 열거 가능한(enumerable) 프로퍼티 키/값/키값쌍배열을 반환
'책' 카테고리의 다른 글
[딥다이브] 21. 빌트인 객체 (1) | 2024.06.04 |
---|---|
[딥다이브] 20. strict mode (0) | 2024.06.04 |
[딥다이브] 19. 프로토타입(1) (0) | 2024.05.23 |
[딥다이브] 18. 함수와 일급 객체 (0) | 2024.05.13 |
[딥다이브] 17. 생성자 함수에 의한 객체 생성 (0) | 2024.05.12 |