💻 프로그래밍

프로토타입

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 루프에서 예상치 못한 속성이 나타나고, 다른 라이브러리와 충돌할 수 있어요. 유틸리티 함수로 분리하세요.

⚠️ 주의사항

🔗 관련 용어

📚 더 배우기