어떤 객체를 원형으로 삼고 이를 복제함으로써 상속과 비슷한 효과를 얻는다.
const instance = new Constructor();
어떤 생성자 함수를 new 연산자와 함께 호출하면 Constructor에서 정의된 내용을 바탕으로 새로운 인스턴스가 생성되는데, 이 인스턴스에는
__proto__
(던더 프로토)라는 Constructor의 prototype 프로퍼티를 참조하는 프로퍼티가 자동으로 부여된다.
인스턴스가 자신의 생성자 함수가 무엇인지를 알고자 할 때 필요한 수단이다.
constructor를 변경하더라도 참조하는 대상이 변경될 뿐, 이미 만들어진 인스턴스의 원형이 바뀐다거나 데이터 타입이 변하는 것은 아니다.
생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 해당 메서드나 프로퍼티에 접근할 수 있다.
열거 가능한 프로퍼티. for in 등으로 객체의 프로퍼티 전체에 접근하고자 할 때 접근 가능 여부를 색상으로 구분지어 표기하는 것이다.
__proto__
는 생략 가능한 속성이라서, 인스턴스는 Constructor.prototype
의 메서드를 호출할 수 있다.
instance.__proto__
와 같은 방식으로 접근하는 것보다는Object.getPrototypeOf()
/Object.create()
로 접근하는 것을 권장한다.
const Cat = function (name) {
this._name = name;
};
Cat.prototype.getName = function() {
return this._name;
};
const tomi = new Cat('Tomi', 10);
tomi.getName(); // Tomi (this = tomi)
//tomi.__proto__라는 객체 내부에 name 프로퍼티가 없으므로 '찾고자 하는 식별자가 정의돼 있지 않을 때' undefined를 반환한다.
tomi.__proto__.getName(); // undefined ??? (this = tomi.__proto__)
tomi.__proto__._name = "__proto__Tomi"
tomi.__proto__.getName(); // __proto__Tomi
인스턴스가 직접 호출할 수 없고 클래스(생성자 함수)에 의해서만 호출할 수 있다.
__proto__
프로퍼티 내부에 다시 __proto__
프로퍼티가 연쇄적으로 이어진 것.
__proto__
안에 __proto__
를 찾아가는 과정
Object.prototype
에 당도하게 된다.여기에는 모든 데이터 타입에서 사용할 수 있는 범용적인 메서드만이 존재하며, 객체 전용 메서드는 Object 생성자 함수에 Static 하게 담겨있다.
프로토타입 객체 안에 정의할 수가 없다. this의 사용을 포기하고 대상 인스턴스를 인자로 직접 주입해야 한다.
Object.create
를 이용하면 Object.prototype
메서드에 접근할 수 없는 경우가 있다.Object.create(null)
은 __proto__
가 없는 객체를 생성한다.
내장 메서드 및 프로퍼티들이 제거됨으로써 기본 기능에 제약이 생기는 대신, 객체 자체의 무게가 가벼워져 성능상 이점을 가진다.
원본 메서드 위에 메서드를 덮어쓰는 것.
prototype에 있는 메서드에 접근하기 위해서는 this가 인스턴스를 바라보도록(call/apply 활용) 하면 된다.