TIL.63 Core J.S - 6. 프로토타입

Haiin·2021년 3월 17일
0

CoreJS

목록 보기
6/7
post-thumbnail

출저

  • 코어자바스크립트 - 정재남


프로토타입

어떤 객체를 원형(prototype)으로 삼고 이를 복제(참조)함으로써 상속과 비슷한 효과를 얻는 유형을 프로토타입이라고 한다.



1. 프로토타입의 개념

1.1 constructor, prototype, instance

  • 어떤 생성자 함수 (Constructor)를 new 연산자와 함께 호출하면,
  • Constructor 에서 정의된 내용을 바탕으로 새로운 인스턴스(instance) 가 생성.
  • 이때 instance 에는 proto 라는 프로퍼티가 자동으로 부여되는데,
  • 이 프로퍼티는 Constructor의 prototype 이라는 프로퍼티를 참조한다.
  • let instance = new Constructor()
let Person = function (name) {
  this._name = name;
}; // 1.생성자 함수 (Constructor)

Person.prototype.getName = function () {
  return this._name;
}  

let haiin = new Person('Haiin'); // 2.연산자 new 와 함께 haiin 이라는 인스턴스 생성

console.log(haiin)
// Person {
//  _name: 'Haiin',
//  __proto__: Person { constructor: ƒ Person(), getName: ƒ () }

// 3.인스턴스에는 __proto__라는 프로퍼티가 자동으로 부여됨, Constructor 의 prototype 이라는 프로퍼티를 참조한다.

haiin.__proto__.getName(); // undefined --(1)
  
  1. getName() 은 this._name 이므로 this 가 가르키는 곳을 보게되면 haiin.__proto__ 가 되고 프로퍼티에 name 이 없기 때문에 찾고자 하는 식별자가 정의돼 있지 않을 때는 Error 대신 undefined 를 반환한다 라는 자바스크립트 규약에 의해 undefined 을 반환한다.

  2. __proto__ 는 생략 가능하다.


1.2 constructor 프로퍼티

  • 생성자 함수의 프로퍼티인 prototype 객체 내부와 인스턴스의 __proto__ 객체 내부에 constructor 라는 프로퍼티가 존재하고 생성자 함수(자기자신)을 참조한다.
  • constructor 프로퍼티로부터 그 원형이 무엇인지를 알 수 있는 수단이 된다.
  • constructor 는 읽기 전용 속성이 부여된 예외적인 경우(기본형 리터럴 변수 - number, string, boolean)을 제외하고는 값을 바꿀 수 있다.
let Person = function (name) {
  this.name = name;
};

let p1 = new Person('사람1') //{name : '사람1'} true
let p1Proto = Object.getPrototypeOf(p1)
let p2 = new Person.prototype.constructor('사람2') //{name : '사람2'} true
let p3 = new p1Proto.constructor('사람3') //{name : '사람3'} true
let p4 = new p1.__proto__.constructor('사람4') //{name : '사람4'} true
let p5 = new p1.constructor('사람5') //{name : '사람5'} true


[p1, p2, p3, p4, p5].forEach(function (p) {
  console.log(p, p instanceof Person)
})
// 모두 동일한 대상을 가리킨다.


2. 프로토타입 체인

2.1 메서드 오버라이드

인스턴스가 동일한 이름의 프로퍼티 또는 메서드를 가지고 있는 상황에서 __proto__ 이 생략되어 불려진 것이 아닌 메서드가 호출된 상황.

  • 원본을 제거하고 다른 대상으로 교체한 것이 아닌, 메서드 위에 메서드를 덮어씌웠다는 표현.
let Person = function (name) {
  this.name = name;
};

Person.prototype.getName = function () {
  return this.name
}

let iu = new Person('지금')

console.log(iu)

iu.getName = function () {
  return '바로' + this.name
}

console.log(iu.getName()) // 바로 지금
// 바로 위의 메서드를 호출, 만약 아래의 proto 가 생략이 되었다면 undefined 가 결과로 나와야 함
console.log(iu.__proto__.getName()) // undefined

2.2 프로토타입 체인

어떤 데이터의 __proto__ 프로퍼티 내부에 다시 __proto__ 프로퍼티가 연쇄적으로 이어진 것을 프로토타입 체인(prototype chain) 이라 하고, 이 체인을 따라가며 검색하는 것을 프로토타입 체이닝(prototype chaining) 이라고 한다.


2.3 객체 전용 메서드의 예외사항


2.4 다중 프로토타입 체인



0개의 댓글