JavaScript는 prototype 기반의 언어다.
→ 어떤 객체를 원형(prototype)으로 삼고, 이를 복제(참조)함으로서 상속과 비슷한 효과를 얻음
//도식에 대한 코드
var instance = new Constructor();
→ Constructor를 new
연산자와 함게 호출
→ Constructor에서 정의된 내용을 바탕으로 instance 생성
→ 이때, instance에는 __proto__
라는 프로퍼티가 자동으로 부여
→ 이 프로퍼티는 Constructor의 prototype
이라는 프로퍼티를 참조
prototype
과 __proto__
모두 객체prototype
객체 내부에는 인스터스가 사용할 메서드를 저장__proto__
를 통해 이 메서드에 접근 가능__proto__
는 생략 가능한 프로퍼티//Constructor
var Person = function (name){
this._name = name;
};
Person.prototype.getName = function(){
return this._name;
}
→ Person의 인스턴스는 __proto__
프로퍼티를 통해 getName을 호출할 수 있다.
//instance
var daeseong = new Person('daeseong')
Person.prototype === daeseong.__proto__ // true
daeseong.__proto__.getName(); // undefined
prototype
을 daeseong의 __proto__
가 참조를 하는 것이 맞는데, getName의 실행값이 undefined가 나온다.daeseong.__proto__.getName()
에서 getName함수 내부에서의 this는 daeseong.__proto__
가 되는 것daeseong.__proto__
에는 _name이 정의되어 있지 않으므로, undefined가 반환된 것__proto__
없이 인스턴스에서 곧바로 메서드를 쓰는 것daeseong.getName(); // daeseong
__proto__
를 빼면 신기하게도 this는 인스턴스가 되고, 메서드도 호출되면서 원하는 값이 나온다.__proto__
는 생략 가능한 프로퍼티이기 때문이다.__proto__
가 생략된 구조→ Constructor를 new
연산자와 함게 호출
→ Constructor에서 정의된 내용을 바탕으로 instance 생성
→ 이때, instance에는 __proto__
라는 프로퍼티가 자동으로 부여
→ 이 프로퍼티는 Constructor의 prototype
이라는 프로퍼티를 참조
*→__proto__
는 생략 가능하도록 구현돼 있기 때문에, Constructor의 prototype에 어떤 메서드나 프로퍼티가 있다면, 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 된다.
__proto__
객체에도 마찬가지로 존재한다. 이 프로퍼티는 원래의 생성자 함수(자기 자신)을 참조한다.→ 인스턴스로부터 그 원형이 무엇인지를 알 수 있는 수단이다.
// 모두 Constructor라는 동일한 대상을 가리킨다.
[Constructor]
[instance].__proto__.constructor
[instance].constructor
Object.getPrototypeOf([instance]).constructor
[Constructor].prototype.constructor
정재남, 『코어 자바스크립트 : 핵심 개념과 동작 원리로 이해하는 자바스크립트 프로그래밍』, 위키북스(2019)