[딥다이브] 19장 프로토타입(3)

N·2023년 6월 20일
0

딥다이브 스터디

목록 보기
10/11

오버라이딩과 프로퍼티 섀도잉

  • 프로토타입이 소유한 프로퍼티(메서드 포함)를 프로토타입 프로퍼티, 인스턴스가 소유한 프로퍼티를 인스턴스 프로퍼티라고 한다.
  • 프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면 인스턴스 프로퍼티로 추가한다. 프로토타입의 프로퍼티는 변화가 없다.
  • 오버라이딩: 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의하여 사용하는 방식
  • 이때 인스턴스의 프로퍼티는 프로토타입의 프로퍼티를 오버라이딩하고, 프로토타입의 프로퍼티가 가려지는 현상을 프로퍼티 섀도잉이라고 한다.

    (이미지 출처: https://velog.io/@rlatp1409/JS-프로토타입-체인-오버라이딩-프로퍼티-섀도잉)
  • 인스턴스가 오버라이딩한 프로퍼티를 삭제할 경우 프로토타입의 프로퍼티가 상속된다.
  • 하위 객체를 통해 프로토타입의 프로퍼티를 변경 또는 삭제하는 것은 불가능하다. 다시 말해 하위 객체를 통해 프로토타입의 get 액세스는 허용되나 set 액세스는 허용되지 않는다.
  • 따라서 프로토타입의 프로퍼티를 변경 또는 삭제하려면 프로토타입에 직접 접근해야 한다.

프로토타입의 교체

  • 프로토타입은 임의의 다른 객체로 변경할 수 있다.

  • 이것은 부모 객체인 프로토타입을 동적으로 변경할 수 있다는 것을 의미한다.

  • 프로토타입은 생성자 함수 또는 인스턴스에 의해 교체할 수 있다.

  • 생성자 함수에 의한 프로토타입의 교체

    • 생성자 함수의 prototype 프로퍼티에 새로운 객체를 할당하여 프로토타입을 교체할 수 있다.
    • 프로토타입으로 교체하는 객체에 constructor 프로퍼티를 추가하여 constructor 프로퍼티와 생성자 함수 간의 연결을 설정한다.(e.g. Person.prototype = {constructor: Person, sayHello() {함수}})
  • 인스턴스에 의한 프로토타입의 교체

    • 프로토타입은 생성자 함수의 prototype 프로퍼티뿐만 아니라 인스턴스의 _ _ proto _ 접근자 프로퍼티(또는 Object.getPropertyOf 메서드)를 통해 접근할 수 있고 프로토타입을 교체할 수도 있다.(e.g. Object.setPrototypeOf(인스턴스, 교체할 객체) 또는 인스턴스. _ proto _ _ = 교체할 객체)
    • 생성자 함수의 prototype 프로퍼티에 다른 임의의 객체를 바인딩하는 것은 미래에 생성할 인스턴스의 프로토타입을 교체하는 것이다. _ _ proto _ _ 접근자 프로퍼티를 통해 프로토타입을 교체하는 것은 이미 생성된 객체의 프로토타입을 교체하는 것이다.
  • 생성자 함수에 의한 프로토타입 교체와 인스턴스에 의한 프로토타입 교체에는 다음과 같은 차이가 있다.

    (이미지 출처: https://velog.io/@rlatp1409/JS-프로토타입-체인-오버라이딩-프로퍼티-섀도잉)

  • 프로토타입으로 교체한 객체 리터럴에 constructor 프로퍼티를 추가하고 생성자 함수의 prototype 프로퍼티를 재설정하여 프로토타입과 생성자함수 간의 파괴되었던 연결을 되살리는 방법은 다음과 같다.

function Person(name) {
  this.name = name;
}

const me = new Person('Lee');

// 프로토타입으로 교체할 객체
const parent = {
	// constructor 프로퍼티와 생성자 함수 간의 연결을 설정 
  constructor: Person,
  sayHello() {
   console.log(`Hi! My name is ${this.name}`);
  }
};

// 생성자 함수의 prototype 프로퍼티와 프로토타입 간의 연결을 설정
Person.prototype = parent;

// me 객체의 프로토타입을 parent 객체로 교체한다.
Object.setPrototypeOf(me, parent);
// 위 코드는 아래 코드와 동일하게 동작한다.
// me.__proto__ = parent;

me.sayHello(); // Hi! My name is Lee

// constructor 프로퍼티가 생성자 함수를 가리킨다. 
console.log(me.constructor === Person); // true
console.log(me.constructor === Object); // false

// 생성자 함수의 prototype 의 프로퍼티가 교체된 프로토타입을 가리킨다.
console.log(Person.prototype === Object.getPrototypeOf(me); // true
profile
web

0개의 댓글