프로토타입
Prototype
JavaScript의 상속 메커니즘. 객체가 다른 객체로부터 속성/메서드를 상속.
Prototype
JavaScript의 상속 메커니즘. 객체가 다른 객체로부터 속성/메서드를 상속.
프로토타입(Prototype)은 JavaScript의 객체 상속 메커니즘입니다. 모든 JavaScript 객체는 [[Prototype]]이라는 내부 슬롯을 가지며, 이를 통해 다른 객체의 속성과 메서드를 상속받습니다. 클래스 기반 상속과 달리 객체가 직접 다른 객체를 상속하는 프로토타입 기반 상속을 사용합니다.
객체의 속성에 접근할 때 해당 속성이 없으면 프로토타입 체인을 따라 올라가며 검색합니다. 예를 들어 arr.toString()을 호출하면 배열 객체 → Array.prototype → Object.prototype 순으로 검색합니다. 이를 프로토타입 체인이라 합니다.
__proto__는 객체의 프로토타입에 접근하는 비표준 방법이었지만, ES6부터 Object.getPrototypeOf()와 Object.setPrototypeOf()가 표준이 되었습니다. 생성자 함수의 prototype 프로퍼티는 new로 생성된 인스턴스의 [[Prototype]]이 됩니다.
ES6의 class 문법은 프로토타입의 문법적 설탕(syntactic sugar)입니다. class로 작성해도 내부적으로는 프로토타입 기반으로 동작합니다. 프로토타입을 이해하면 JavaScript의 상속, this 바인딩, 내장 객체 확장 등을 깊이 이해할 수 있습니다.
// JavaScript 프로토타입 예제
// 1. 프로토타입 체인 확인
const arr = [1, 2, 3];
console.log(arr.__proto__ === Array.prototype); // true
console.log(Array.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null (체인의 끝)
// 2. 생성자 함수와 프로토타입
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, I'm ${this.name}`);
};
const alice = new Person('Alice');
alice.greet(); // "Hello, I'm Alice"
console.log(alice.__proto__ === Person.prototype); // true
// 3. Object.create로 상속
const animal = {
speak() {
console.log(`${this.name} makes a sound`);
}
};
const dog = Object.create(animal);
dog.name = 'Rex';
dog.bark = function() {
console.log('Woof!');
};
dog.speak(); // "Rex makes a sound"
// 4. ES6 클래스 (프로토타입의 문법적 설탕)
class Vehicle {
constructor(brand) {
this.brand = brand;
}
info() {
return `Brand: ${this.brand}`;
}
}
class Car extends Vehicle {
constructor(brand, model) {
super(brand);
this.model = model;
}
info() {
return `${super.info()}, Model: ${this.model}`;
}
}
// 5. 프로토타입 메서드 확인
console.log(Car.prototype.isPrototypeOf(new Car('Toyota', 'Camry'))); // true
시니어: 배열에 커스텀 메서드를 추가하고 싶은데, Array.prototype을 수정할까요?
주니어: 그러면 모든 배열에 적용되겠네요!
시니어: 네, 하지만 내장 프로토타입 수정은 위험해요. 다른 라이브러리와 충돌할 수 있어서 유틸리티 함수나 서브클래스로 만드는 게 안전합니다.
면접관: __proto__와 prototype의 차이점을 설명해주세요.
지원자: __proto__는 모든 객체가 가진 내부 링크로 해당 객체의 프로토타입을 가리킵니다. prototype은 함수 객체만 가지며, new로 인스턴스를 만들 때 인스턴스의 __proto__가 이 prototype을 참조하게 됩니다.
면접관: 프로토타입 체인에서 속성 검색 순서는요?
지원자: 먼저 객체 자체에서 찾고, 없으면 __proto__를 따라 올라가며 검색합니다. Object.prototype까지 올라가도 없으면 undefined를 반환합니다.
리뷰어: Object.prototype에 메서드를 추가했는데, 이건 안티패턴이에요.
작성자: 모든 객체에서 편하게 쓰려고요.
리뷰어: for...in 루프에서 예상치 못한 속성이 나타나고, 다른 라이브러리와 충돌할 수 있어요. 유틸리티 함수로 분리하세요.