객체는 리터럴 표기법 또는 생성자 함수에 의해 생성되고 리터럴 표기법에 의해 생성된 객체도 생성자 함수와 연결되므로, 결국 모든 객체는 생성자 함수와 연결되어 있다.
프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성된다. 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍으로 존재하기 때문이다.
생성자 함수는 사용자가 직접 정의한 사용자 정의 생성자 함수와 자바스크립트가 기본 제공하는 빌트인 생성자 함수로 구분할 수 있다.
사용자 정의 생성자 함수와 프로토타입 생성 시점
빌트인 생성자 함수와 프로토타입 생성 시점
객체 생성 방법
객체 리터럴에 의해 생성된 객체의 프로토타입
Object 생성자 함수에 의해 생성된 객체의 프로토타입
생성자 함수에 의해 생성된 객체의 프로토타입
new 연산자와 함께 생성자 함수를 호출하여 인스턴스를 생성하면 다른 객체 생성 방식과 마찬가지로 추상 연산 OrdinaryObjectCreate가 호출된다. 이때 OrdinaryObjectCreate에 전달되는 프로토타입은 생성자 함수의 prototype에 바인딩되어있는 객체다.
표준 빌트인 객체인 Object 생성자 함수와 더불어 생성된 프로토타입인 Object.prototype은 다양한 빌트인 메서드를 가지고 있다. 하지만 사용자 정의 생성자 함수와 더불어 생성된 prototype의 프로퍼티는 constructor 뿐이다.
프로토타입은 객체다. 따라서 일반 객체와 같이 프로토타입에도 프로퍼티를 추가/삭제할 수 있다.
function Person(name) {
this.name = name;
}
// 프로토타입 메서드
Person.prototype.sayHello = function() {
console.log(`Hi! My name is ${this.name}`);
};
const me = new Person('Lee');
const you = new Person('Kim');
me.sayHello(); // Hi! My name is Lee
you.sayHello(); // Hi! My name is Kim
생성자 함수에 의해 생성된 객체는 Object.prototype의 메서드인 hasOwnProperty를 호출할 수 있다. 이것은 해당 객체가 생성자 함수의 프로토타입 뿐만 아니라 Object.prototype도 상속받았다는 것을 의미한다.
자바스크립트는 객체의 프로퍼티(메서드)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없으면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 이를 프로토타입 체인이라고 한다. 프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 매커니즘이다.
(이미지 출처: https://iamsjy17.github.io/javascript/2019/06/10/js33_17_prototype.html)
Person객체의 프로토타입 체인은 Person객체->Person.prototype->Object.prototype
자바스크립트 엔진이 메서드를 검색하는 과정
- 먼저 메서드를 호출한 객체에서 메서드를 검색 -> 없으면 프로토타입 체인을 따라 내부 슬롯에 바인딩 되어 있는 프로토타입으로 이동하여 메서드를 검색한다.
- 상위 프로토타입에도 메서드가 없는 경우 프로토타입 체인을 따라 이동하여 메서드를 검색한다.
- 메서드가 존재할 때 자바스크립트 엔진이 해당 메서드를 호출하고, 호출된 메서드의 this에는 가장 처음 메서드를 호출한 객체가 바인딩된다.
프로토타입 체인의 최상위에 위치하는 객체는 언제나 Object.prototype이다.따라서 모든 객체는 Object.prototype 을 상속받는다. 즉 Object.prototype은 프로토타입 체인의 종점이다. Object.prototype의 프로토타입, 즉 [[prototype]] 내부 슬롯의 값은 null이다. Object.prototype에서도 프로퍼티를 검색할 수 없는 경우 에러가 발생하지 않고 undefined를 반환하는 것에 주의
프로토타입은 상속과 프로퍼티 검색을 위한 메커니즘이다. 반면 스코프 체인은 식별자 검색을 위한 메커니즘이다. 프로퍼티가 아닌 식별자는 스코프 체인에서 검색한다.
스코프 체인과 프로토타입 체인은 서로 연관 없이 별도로 동작하는 것이 아니라 서로 협력하여 프로퍼티와 식별자를 검색하는데 사용된다.