자바스크립트는 프로토타입 기반 언어
클래스 기반 언어에서는 상속을 사용하지만
프로토타입 기반 언어에서는 어떤 객체를 원형으로 삼고 이를 복제(참조)함으로써 상속과 비슷한 효과를 냄.
__proto__
라는 프로퍼티가 자동으로 부여prototype와
__proto__
는 객체
prototype 객체 내부에는 인스턴스가 사용할 메서드를 저장
인스턴스에서도 숨겨진 프로퍼티인__proto__
를 통해 이 메서드에 접근 가능
하지만 실무에서는 직접 던더프로토에 접근하는것이 권장되지 않음.
Object.getPrototypeOf()
/Object.create()
등을 대신 이용
만약 person이라는 생성자 함수의 prototype에 getName이라는 메서드를 지정시
let Person = function(name){
this._name = name;
}
Person.prototype.getName = function() {
return this._name;
}
Person의 인스턴스는 __proto__
프로퍼티를 통해 getName을 호출 가능
만약 여기서 새로운 인스턴스를 생성한다면,
let apple = new Person('Suzi');
apple.__proto__.getName(); //undefined
apple의 던더프로토가 참조하는 name은 Person의 name이기 때문에, 현재 아무 값도 할당되어있지 않아 undefined가 출력됨.
따라서 다음과 같은 공식이 성립한다는 것을 알 수 있음
Person.prototype === apple.__proto__ // true
인스턴스의 던더프로토는 생략 가능하기 때문에 다음과 같은 공식도 성립
Person.prototype === apple // true
따라서 정리해본다면, new 연산자로 Constructor를 호출하면 instance가 만들어지는데, 이 instance의 생략 가능한 프로퍼티인 __proto__
는 Constructor의 prototype을 참조함.
생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면, 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게됨.
원래의 생성자함수(자기 자신)을 참조하는 프로퍼티
인스턴스로부터 그 원형이 무엇인지 알 수 있는 수단
인스턴스에서 contructor에 직접적인 접근이 가능
constructor는 읽기 속성이 부여된 예외적인 경우를 제외하고 값 변경 가능
(읽기 속성이 부여된 예외적인 경우 : 기본형 리터럴 변수 - number, string, boolean)
참조하는 대상이 변경될 뿐 이미 만들어진 인스턴스의 원형이 바뀐다거나 데이터 타입이 변하는 것은 아님.= 어떤 인스턴스의 생성자 정보를 알아내기 위해 constructor 프로퍼티에 의존하는 것이 항상 안전하진 않음.
[Constructor]
[instance].__proto__.constructor
[instance].constructor
Object.getPrototypeOf([instance]).constructor
[Constructor].prototype.constructor
[Constructor].prototype
[instance].__proto__
[instance]
Object.getPrototypeOf([instance])
만약 인스턴스가 동일한 이름의 프로퍼티 또는 메서드를 가지고 있다면?
자바스크립트 엔진이 getName이라는 메서드를 찾는 방식은 가장 가까운 대상인 자신의 프로퍼티를 검색 후, 없으면 그 다음으로 가까운 대상인 __proto__
를 검색하는 순서로 진행하기 때문에 인스턴스의 메서드 우선 실행
만약 메서드 오버라이딩이 이뤄진 상태에서 원본의 메서드에 접근하고 싶다면
apple.__proto__.getName() //원본의 getName 출력
모든 객체의 __proto__
에는 Object.prototype이 연결
프로토타입 체인 : 어떤 데이터의 __proto__
프로퍼티 내부에 다시 __proto__
프로퍼티가 연쇄적으로 이어진 것
프로토타입 체이닝 : 이 체인을 따라가며 검색하는 것
메서드 오버라이딩과 동일한 동작방식으로, 어떤 메서드 호출 시 자바스크립트 엔진은 데이터 자신의 프로퍼티들을 검색해 찾던 메서드가 있으면 그 메서드를 실행하고 없으면 __proto__
를 검색해 실행하는 방식
Object.prototype
이 아닌 Object에 스태틱 메서드(static method)
로 부여생성자 함수인 Object와 인스턴스인 객체 리터럴 사이에는 this를 통한 연결이 불가능해 대상 인스턴스를 인자로 직접 주입해야 함.
대각선의 __proto__
를 연결해나가기만 하면 무한대로 체인 연결 가능
__proto__
를 연결하는 방법__proto__
가 가리키는 대상, 즉 생성자 함수의 prototype이 연결하고자 하는 상위 생성자 함수의 인스턴스를 바라보도록
좋네요 ,,,