Mingyu Kim

Prototypes

프로토타입(Prototype)은 JavaScript가 상속을 구현하는 방식이자, 모든 객체가 다른 객체로부터 속성과 메서드를 상속받을 수 있도록 하는 메커니즘이다.

간단히 말해, 프로토타입은 “객체들의 공유 자원” 또는 “부모 객체의 설계도” 역할을 한다.

1. 프로토타입의 기본 개념: 공유와 상속

JavaScript의 모든 객체는 생성될 때 자신과 연결된 다른 객체(부모 객체)를 가진다. 이 연결된 부모 객체가 바로 프로토타입 객체다.

1.1. 객체는 어떻게 속성을 찾을까?

어떤 객체에서 속성이나 메서드를 호출하면,

  1. 객체 자신이 그 속성을 가지고 있는지 먼저 확인
  2. 해당 속성이 없다면, 연결된 프로토타입 객체로 이동하여 그곳에서 속성을 찾음
  3. 이 과정을 반복하며 계속해서 상위 프로토타입을 따라 올라가는데, 이를 프로토타입 체인(Prototype Chain)이라고 함

2. 두 가지 주요 속성 이해하기

프로토타입 개념을 이해하기 위해 객체와 함수가 가진 두 가지 핵심 속성을 구분해야 한다.

2.1. [[Prototype]] (또는 __proto__)

2.2. prototype 속성

3. 프로토타입 체인 (The Prototype Chain)

프로토타입 체인은 JavaScript 상속의 핵심으로, 속성을 찾기 위해 부모 객체로 연결된 고리를 따라 이동하는 일련의 과정이다.

3.1. 체인의 동작 예시

다음은 객체를 생성하고 속성을 찾는 과정이다.

// 1. 생성자 함수 (미래 객체의 설계도)
function Person(name) {
  this.name = name;
}

// 2. Person.prototype에 메서드 추가 (공유할 자원)
Person.prototype.sayHello = function() {
  console.log(`안녕하세요, 저는 ${this.name}입니다.`);
};

// 3. Person 생성자를 통해 'person1' 객체 생성
const person1 = new Person('철수');

// 4. 메서드 호출
person1.sayHello(); // 출력: 안녕하세요, 저는 철수입니다.

// 5. 속성 검색 과정 (프로토타입 체인)
// (1) person1 객체에서 sayHello를 찾는다. (없음)
// (2) person1의 [[Prototype]]이 가리키는 Person.prototype에서 sayHello를 찾는다. (찾음!)
// (3) 함수 실행.

3.2. 체인의 종점 (Object.prototype)

모든 객체는 최종적으로 Object.prototype을 상속받는다. 이 객체는 모든 JavaScript 객체가 공통으로 사용하는 기본 메서드들(예: toString(), hasOwnProperty())을 가지고 있다.

프로토타입 체인의 맨 끝은 null이며, null에 도달할 때까지 속성을 찾지 못하면 undefined를 반환한다.

4. 핵심 정리 및 용어 비교

용어 설명 접근 방법
prototype 생성자 함수가 가지는 속성. 이 함수로 생성될 객체들의 부모 역할을 할 객체(공유 공간)를 가리킨다. Function.prototype
[[Prototype]] 객체가 가지는 내부 속성. 자신이 상속받는 부모 객체를 가리킨다. Object.getPrototypeOf(객체) 또는 객체.__proto__
프로토타입 체인 원하는 속성을 찾을 때까지 [[Prototype]] 연결 고리를 따라 상위 객체로 이동하는 과정. -

5. class 문법과 프로토타입

ES6에서 도입된 class 문법은 프로토타입 기반 상속을 더욱 쉽게 사용하기 위한 문법적 설탕(Syntactic Sugar)일 뿐이다. class를 사용해도 내부적으로는 여전히 프로토타입 체인을 통해 상속이 이루어진다.

// ES6 class 문법
class Animal {
  constructor(name) {
    this.name = name;
  }
  // 이 메서드는 자동으로 Animal.prototype에 추가됨
  speak() {
    console.log(`${this.name}이(가) 소리를 냅니다.`);
  }
}

const cat = new Animal('야옹이');
cat.speak(); // 프로토타입 체인을 통해 Animal.prototype.speak() 호출