
자바스크립트는 프로토타입 기반(prototype-based) 언어입니다.
클래스 기반 객체지향 언어와는 다르게, 객체가 또 다른 객체를 상속받는 구조를 통해
유연하고 동적인 상속을 구현합니다.
자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체인 프로토타입 객체를 참조합니다.
이렇게 객체가 또 다른 객체를 참조하면서 프로퍼티나 메서드를 물려받을 수 있게 되는 구조가
바로 프로토타입 체인(Prototype Chain)입니다.
__proto__ vs prototype| 구분 | 설명 |
|---|---|
__proto__ | 모든 객체가 가지고 있는 내부 프로퍼티로, 자신의 프로토타입을 참조함 |
prototype | 함수(생성자 함수 포함) 객체에만 존재. 해당 함수를 new로 생성한 인스턴스의 proto가 참조하게 됨 |
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function () {
console.log(`Hi, I'm ${this.name}`);
};
const user = new Person("현중");
user.sayHi(); // Hi, I'm 현중
console.log(user.__proto__ === Person.prototype); // true
// new 생성자로 인해 __proto__은 생성자 함수 prototype으로 연결하기 때문
// function Animal(name) {
// 1. this = {}; (빈 객체 생성) -> 프로토타입 체인 연결
// this.name = name;
// 2. this.__proto__ = Animal.prototype;
// 3. return this;
}
객체에서 프로퍼티나 메서드를 접근할 때,
자신의 프로퍼티에 없다면 __proto__ 를 따라 상위 프로토타입으로 계속 탐색합니다.
user.toString();
// user → Person.prototype → Object.prototype 에서 toString 탐색
// 즉, 객체는 존재하지 않는 멤버를 프로토타입 체인 상단까지 거슬러 올라가며 찾습니다.
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function () {
console.log(`${this.name} is eating`);
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype); // 프로토타입 상속
Dog.prototype.constructor = Dog;
// constructor 재선언 -> 원래있던 constructor가 없어지기 때문에
const myDog = new Dog("멍멍이");
myDog.eat(); // 멍멍이 is eating
객체 리터럴로 만든 모든 객체는 자동으로 Object.prototype을 상속받습니다.
const obj = {};
console.log(obj.__proto__ === Object.prototype); // true
| 개념 | 설명 |
|---|---|
__proto__ | 모든 객체에 존재하는 숨겨진 프로퍼티. 객체가 참조하는 실제 프로토타입 객체를 가리킴 |
prototype | 생성자 함수에만 존재하는 프로퍼티. 이 함수를 통해 생성된 인스턴스가 상속받게 되는 객체 |
| 프로토타입 체인 | 객체와 그 프로토타입 객체들이 __proto__로 연결된 구조. 상속처럼 작동하여, 원하는 속성이나 메서드를 위로 거슬러 올라가며 탐색 |
Object.create(proto) | 인자로 전달된 객체를 프로토타입으로 갖는 새로운 객체를 생성함. 상속 구조를 명확히 설정할 때 유용 |