프로토타입 체인
프로토타입 체인
개요
프로토타입 체(Prototype Chain)은 자바스크립트(JavaScript)에서 객체 간 상속을 구현하는 핵심 메커니즘입니다. 자바스크립트는 전통적인 클래스 기반 객체지향 언어(C++, Java 등)와 달리 프로토타입 기반(prototype-based) 언어로, 객체가 직접 다른 객체를 자신의 원형(prototype)으로 참조함으로써 속성과 메서드를 상속받는 방식을 사용합니다. 이 구조를 통해 코드 재사용성과 객체 간 계층적 관계를 효과적으로 구현할 수 있습니다.
프로토타입 체인은 자바스크립트의 동작 원리 중 하나로, 객체의 속성이나 메서드를 찾을 때 해당 객체 자체에 존재하지 않으면, 자동으로 그 객체의 프로토타입을 따라 올라가며 탐색을 수행합니다. 이 과정은 최상위 프로토타입인 [Object.prototype](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/Object.prototype)에 도달할 때까지 지속되며, 이를 프로토타입 체인 탐색(prototype chain lookup)이라고 합니다.
프로토타입의 개념
프로토타입이란?
모든 자바스크립트 함수는 생성될 때 자동으로 prototype이라는 특수한 속성을 가지며, 이 속성은 객체를 가리킵니다. 이 객체는 해당 함수로 생성된 인스턴스들이 공유할 수 있는 속성과 메서드를 정의하는 공간입니다.
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, I'm ${this.name}`);
};
const john = new Person('John');
john.greet(); // "Hello, I'm John"
위 예제에서 john 객체는 greet 메서드를 직접 정의하지 않았지만, Person.prototype에 정의된 메서드를 프로토타입 체인을 통해 접근할 수 있습니다.
프로토타입 체인의 작동 방식
1. 속성 탐색 과정
객체의 속성에 접근할 때, 자바스크립트 엔진은 다음과 같은 순서로 탐색을 수행합니다:
- 객체 자체에 속성이 존재하는지 확인
- 존재하지 않으면, 객체의
[[Prototype]](내부 슬롯)을 참조하여 프로토타입 객체로 이동 - 프로토타입 객체에서 속성 탐색 반복
- 최종적으로
Object.prototype에 도달하거나, 속성을 찾을 때까지 계속
const obj = {};
console.log(obj.toString()); // Object.prototype에 정의된 메서드
obj는 toString을 직접 정의하지 않았지만, Object.prototype에 정의되어 있어 호출 가능합니다.
2. [__proto__](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/__proto__)와 [Object.getPrototypeOf](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/Object.getPrototypeOf)()
객체의 프로토타입은 __proto__ 속성(비권장) 또는 표준 메서드 Object.getPrototypeOf()로 접근할 수 있습니다.
const person = new Person('Jane');
console.log(Object.getPrototypeOf(person) === Person.prototype); // true
⚠️ 주의:
__proto__는 비권장 속성이므로, 가능하면Object.getPrototypeOf()와[Object.setPrototypeOf](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/Object.setPrototypeOf)()를 사용하는 것이 좋습니다.
프로토타입 체인의 계층 구조
자바스크립트의 표준 객체 계층은 다음과 같은 구조를 가집니다:
자신의 인스턴스
↓
생성자.prototype
↓
Object.prototype
↓
null
예를 들어:
function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const dog = new Dog();
console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null
이 구조는 다중 상속과 유사한 계층을 형성하며, 자식 객체가 부모 객체의 기능을 상속받도록 합니다.
ES6 클래스와 프로토타입 체인
ES6에서는 [class](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/class) 키워드를 도입하여 문법적으로 클래스 기반 언어처럼 보이게 했지만, 내부적으로는 여전히 프로토타입 체인을 기반으로 동작합니다.
class Animal {
speak() console.log('Animal speaks');
}
}
class Dog extends Animal {
bark() {
console.log('Woof!');
}
}
const dog = new Dog();
dog.speak(); // Animal.prototype에서 상속
dog.bark(); // Dog.prototype에 정의
여기서 Dog.prototype은 Animal.prototype을 상속받으며, 프로토타입 체인이 형성됩니다.
주의사항과 성능 고려
- 프로토타입 체인이 길어질수록 속성 탐색에 시간이 더 걸릴 수 있습니다.
- 프로토타입에 정의된 속성은 모든 인스턴스가 공유하므로, 상태(state)를 가지는 데이터는 인스턴스 자체에 정의해야 합니다.
for...in루프는 프로토타입 체인에 있는 모든 열거 가능한 속성을 포함하므로,[hasOwnProperty](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/hasOwnProperty)()를 사용해 필터링하는 것이 좋습니다.
for (let key in dog) {
if (dog.hasOwnProperty(key)) {
console.log(key); // 인스턴스 고유 속성만 출력
}
}
관련 문서 및 참고 자료
- MDN Web Docs - 프로토타입 상속
- You Don't Know JS: this & Object Prototypes
- ECMAScript 표준 - 6.1.7 Object Internal Methods and Internal Slots
프로토타입 체인은 자바스크립트의 핵심 개념 중 하나로, 객체지향 프로그래밍을 깊이 이해하기 위해 반드시 숙지해야 할 내용입니다. 이를 통해 효율적이고 유연한 코드 구조를 설계할 수 있습니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.