const test = function () { console.log("hello"); }; // console.log(test.prototype); // {}
일반적으로 자바스크립트의 모든 함수에 자동으로 생성되는 프로퍼티명이다.
일반적으로 우리가 생성하는 모든 객체는 Object
생성자 함수를 통해 생성하고 있었다. (때문에 모든 객체는 __proto__
를 갖고 있다. 이는 Array도 마찬가지이며 관련 사항은 밑에서 설명하도록 하겠다.)
__proto__
의 관계// 생성자 함수 (객체를 생성하기 위한 템플릿, ES6 class 나오기 전까지 주로 사용) const Person = function (name) { this.name = name; }; // new 연산자와 함께 호출 const yongmin = new Person("yongmin"); console.log(yongmin); // Person { // name: 'yongmin', // __proto__: { constructor: ƒ Person() } 자동적으로 생성 // }
생성자 함수를 new
연산자와 함께 호출 할경우, 생성자 함수에 정의된 내용을 바탕으로 인스턴스(객체)가 생성된다.
이때 생성된 인스턴스에는 __proto__
라는 프로퍼티가 자동으로 생성된다.(숨겨져 있으며 __proto__
역시 객체이다.)
__proto__
는 생성자 함수의 prototype
프로퍼티를 참조하게 된다.
const Person = function (name) { this.name = name; }; Person.prototype.printName = function () { return this.name; };
생성자 함수의 prototype에는 우리가 사용할 수 있는 메소드들이 존재하며, 위처럼 직접 메소드를 지정하여 사용할 수 있다.(prototype은 객체이므로 가능)
생성된 yongmin이라는 인스턴스 값은 __proto__
라는 프로퍼티를 갖고 있으며, 이는 생성자 함수의 prototype
이라는 프로퍼티 값을 참조하므로 관련 속성 및 메소드를 호출하여 사용할 수 있다.
const yongmin = new Person("yongmin"); console.log(yongmin.__proto__.printName()); // undefined yongmin.__proto__.name: 'yongmin' console.log(yongmin.__proto__.printName()); // 'yongmin'
실제로 __proto__
에 접근하여 메소드를 호출하니 undefined
가 나왔다. 이는 this
의 바인딩 문제이다.
함수를 .
뒤에 호출할 경우, 메소드로서 호출이 되며 앞에오는 객체가 this
가 되기 때문이다.
__proto__
라는 객체 안에는 name
이라는 속성명이 없기 때문에 undefined
가 뜬 것이며, name
속성명을 추가로 정해주니 값이 잘 출력됨을 알 수 있었다.
const yongmin = new Person("yongmin"); console.log(yongmin.printName()); // 'yongmin'
__proto__
를 빼면, this
가 해당 인스턴스가 되기 때문에, 정상 작동을 하게 된다.
__proto__
는 생략 가능한 프로퍼티이다.( 생략 가능한 이유는 따로 없고, 이처럼 설계되었다고 한다... )
new
연산자와 함께 생성자 함수를 호출할 시, 객체인 인스턴스가 생성된다.
인스턴스를 생성할 때 기존 생성자 함수가 갖고 있는 prototype
를 참조하는 __proto__
가 생성된다.
__proto__
는 생략이 가능하며, 덕분에 기존 생성자 함수의 prototype
이 갖고 있던 속성값 및 메소드들을 사용할 수 있다.
코어 자바스크립트 책