자바스크립트는 프로토타입 기반 객체지향 프로그래밍 언어로 불린다.
자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다. 그리고 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 한다. 이러한 부모 객체를 Prototype(프로토타입) 객체 또는 줄여서 Prototype(프로토타입)이라 한다.
자바스크립트의 모든 객체는 [[Prototype]]이라는 숨겨진 속성(internal slot)을 갖고 있다. [[Prototype]]은 항상 null 또는, 객체이며 상속을 구현할때 사용된다.
[[Prototype]]의 값은 Prototype(프로토타입) 객체이며 _ proto accessor property로 접근할 수 있다. proto _ 프로퍼티에 접근하면 내부적으로 Object.getPrototypeOf가 호출되어 프로토타입 객체를 반환한다.
함수 객체 앞에 new키워드를 사용하면 생성자가 되고, 이걸로 생성한 객체를 인스턴스라고 한다.
"_ proto _" : 모든 객체가 가지고 있는 속성으로,
객체가 생성될 때 자신의 부모 객체인 프로토타입을 가리킨다!
"prototype" : 함수 객체만이 가지는 프로토타입으로,
함수 객체가 생성자로 사용될 때 인스턴스의 부모 역할을 하는 객체를 가리킨다!
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
console.dir(Person); // prototype 프로퍼티가 있다.
console.dir(foo); // prototype 프로퍼티가 없다.
/* dir(object)
매개변수로 전달된 객체의 속성을 출력한다. */
🍎 [[Prototype]]
함수를 포함한 모든 객체가 가지고 있는 인터널 슬롯이다.
객체의 입장에서 자신의 부모 역할을 하는 프로토타입 객체를 가리키며 함수 객체의 경우 Function.prototype를 가리킨다. 여기서 Function.prototype의 프로토타입 객체는 Object.prototype(프로토타입 체인의 종점)
console.log(Person._ proto _ === Function.prototype);
🍏 prototype 프로퍼티
함수 객체만 가지고 있는 프로퍼티이다.
함수 객체가 생성자로 사용될 때 이 함수를 통해 생성될 객체의 부모 역할을 하는 객체(프로토타입 객체)를 가리킨다.
console.log(Person.prototype === foo._ proto _);
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
// Person() 생성자 함수에 의해 생성된 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(Person.prototype.constructor === Person);
// foo 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(foo.constructor === Person);
// Person() 생성자 함수를 생성한 객체는 Function() 생성자 함수이다.
console.log(Person.constructor === Function);
Person()생성자에 의해 자손인 foo객체가 생성,
foo의 부모는 Person()생성자, 그래서 foo객체의 프로토 타입 객체는 Person.prototype이며, 이 Person.prototype의 constructor 프로퍼티는 Person() 생성자 함수를 가리킨다 !
-자바스크립트는 특정 객체의 프로퍼티나 메소드에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티 또는 메소드가 없다면 [[Prototype]]이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색한다. 이것을 프로토타입 체인이라 한다.
function Person(name, gender) {
this.name = name;
this.gender = gender;
this.sayHello = function(){
console.log('Hi! my name is ' + this.name);
};
}
var foo = new Person('Lee', 'male');
console.dir(Person);
console.dir(foo);
console.log(foo.__proto__ === Person.prototype); // ① true
console.log(Person.prototype.__proto__ === Object.prototype); // ② true
console.log(Person.prototype.constructor === Person); // ③ true
console.log(Person.__proto__ === Function.prototype); // ④ true
console.log(Function.prototype.__proto__ === Object.prototype); // ⑤ true