JS/Javascript

[javascript] 객체 9 / 프로토타입(prototype)

ui-o 2025. 9. 3. 16:21
반응형

프로토타입(prototype)

  • 자바스크립트에서 모든 객체는 다른 객체를 가리키는 링크를 갖고 있음.
    이 링크를 [[Prototype]]이라고 부르며, 흔히 "객체의 부모"처럼 생각할 수 있음
  • 다른 객체를 참조할 수 있는 내부 연결([[Prototype]]) 링크를 통해 객체가 자신에게 없는 속성이나 메서드를 상위 객체에서 찾아서 사용할 수 있음.
객체 → 부모 객체 → 부모의 부모 객체 → ... → Object.prototype → null

왜 프로토타입이 필요한가?

1. 메모리 효율성을 위해

  • 프로토타입을 사용하면 메서드를 객체마다 반복 생성하지 않고 공유 메서드를 하나만 정의하고 모든 객체가 참조 가능
// ex) 공유 메서드 활용 
Person.prototype.sayName = function() {
  return this.name;
};

const p1 = new Person("Alice");
const p2 = new Person("Bob");

console.log(p1.sayName()); // "Alice"
console.log(p2.sayName()); // "Bob"

 

2. 상속 구현

 

  • 자바스크립트는 클래스 기반 언어가 아니라 프로토타입 기반 언어
  • 즉, 객체끼리 속성과 메서드를 쉽게 상속 가능
  • 객체 A가 객체 B의 속성과 메서드를 필요로 할 때, B를 A의 프로토타입으로 연결하면 바로 사용 가능
const parent = { greet: () => "Hi!" };
const child = Object.create(parent);

console.log(child.greet()); // "Hi!" (child는 greet 메서드가 없지만 parent에서 가져옴)

 

3. 프로퍼티 탐색의 일관성

 

  • 프로토타입 체인을 통해 속성 탐색 규칙이 일관되게 유지 (탐색 순서가 명확)
  • child에서 속성을 찾으면 → 자신의 속성 → 부모 속성 → 부모의 부모 … → Object.prototype → 없으면 undefined
  • 이 구조 덕분에 객체 구조를 예측 가능하게 설계할 수 있음

 


프로토타입 체인

  • [[Prototype]] 링크를 통해 자신에게 없는 프로퍼티나 메서드를 부모 객체에서 탐색할 수 있습니다.
    이런 구조를 프로토타입 체인(prototype chain)이라고 부름
  • 프로토타입 체인은 속성 탐색 순서를 결정함

프로퍼티 탐색 시 프로토타입 체인 확인

객체에서 어떤 프로퍼티를 찾을 때, 자바스크립트는 이렇게 탐색

  1. 자기 자신의 프로퍼티를 먼저 확인
  2. 없다면 [[Prototype]]이 가리키는 부모 객체 확인
  3. 부모에도 없다면 그 부모의 부모 확인
  4. 최상위 Object.prototype까지 올라가고, 없으면 null 반환
// 프로토타입 체인 흐름
child → parent → Object.prototype → null
const parent = { greet: () => "hi" };
const child = Object.create(parent); // parent를 프로토타입으로 설정
child.name = "Alice";

console.log(child.name);   // "Alice" (자기 속성)
console.log(child.greet()); // "hi" (프로토타입 체인에서 찾음)

/*
- 여기서 child는 parent를 자신의 프로토타입으로 삼고 있음.
- 따라서 child에 greet가 없어도 parent에서 찾아서 실행됨. 프로토타입 체인 덕분
*/

프로토타입 접근 방법

1. Object.getPrototypeOf()

  • 표준 방식(ES5 이후)으로 객체의 프로토타입을 반환
  • 읽기 전용 접근자 역할만 함 (쓰기 기능은 없음)
  • 안정적이고, 표준화된 방법
  • 프로토타입을 확인만 하고 싶으면 → Object.getPrototypeOf(obj)
  • 프로토타입을 바꿔야 하는 특수한 경우 → Object.setPrototypeOf(obj, newProto)

특징

  • 읽기 전용 → 프로토타입을 변경하려면 Object.setPrototypeOf() 사용
  • 호환성 문제 거의 없음
  • 표준화되어 있어서 협업이나 유지보수 측면에서는 Object.getPrototypeOf()를 쓰는 것이 권장
const parent = { greet: () => console.log("안녕!") };
const child = Object.create(parent);

console.log(Object.getPrototypeOf(child) === parent); // true

/*
- Object.create()로 만든 객체는 직접 지정한 객체를 프로토타입으로 가짐
- Object.getPrototypeOf()를 사용하면 안전하게 확인 가능
*/

2. __proto__

  • 객체의 [[Prototype]]에 직접 접근할 수 있는 속성
  • ES6 이전에는 __proto__를 쓰는 것이 일반적이었지만, 비표준이라는 점 때문에 최신 코드에서는 가급적 사용하지 않는 것이 좋음
  • 객체 리터럴을 만들면 내부적으로 생성됨

특징

  • 읽기쓰기 가능 (getter / setter)
  • 표준 방식은 아니고, 호환성 문제가 있을 수 있음
  • 실제로는 내부 슬롯 [[Prototype]]를 조작하는 편리한 인터페이스
  • 면 프로토타입 체인 구조를 임의로 바꿀 수 있으므로, 유지보수 시 혼동될 수 있음
const parent = { greet: () => console.log("안녕!") };
const child = {};
child.__proto__ = parent;

child.greet(); // 안녕!
console.log(child.__proto__ === parent); // true

함수와 프로토타입

자바스크립트에서 함수는 객체임

  • 따라서 함수도 프로퍼티메서드를 가질 수 있음
  • 특별히 함수 객체는 prototype 속성을 가짐
  • 이 prototype 속성은 주로 생성자 함수와 객체 생성에서 중요하게 사용됨
function Person(name) {
  this.name = name;
}

console.log(typeof Person); // "function"
console.log(Person.prototype); // { constructor: f Person(name) }

/*
Person.prototype은 기본적으로 constructor 프로퍼티를 가지고 있음
*/

생성자 함수와 프로토타입

  • 함수를 생성자 함수(Constructor Function)로 사용하면,
    new 키워드로 객체를 만들 때 생성된 객체의 [[Prototype]]이 바로 생성자 함수의 prototype으로 연결됨
function Person(name) {
  this.name = name;
}

// 생성자 함수가 만든 객체들이 공유하는 메서드를 정의
Person.prototype.sayHello = function() {
  console.log(`안녕, 나는 ${this.name}야!`);
};

// 생성자 함수 호출 시, 새 객체의 [[Prototype]]을 함수의 prototype에 연결
const alice = new Person("앨리스");

// 여러 객체가 같은 메서드를 사용 가능
alice.sayHello(); // 안녕, 나는 앨리스야!
console.log(Object.getPrototypeOf(alice) === Person.prototype); // true

/*
- alice 객체에는 sayHello 메서드가 없지만, 
  프로토타입 체인을 통해 Person.prototype.sayHello를 호출할 수 있음
*/
// 예시 코드 프로로타입 체인
Person.prototype
 └─ sayHello()
alice ──> [[Prototype]] ──> Person.prototype ──> Object.prototype ──> null

References

 

  • Object.create() 사용법

 

 

 

[javascript] 객체 7 / 객체 내장 메서드

객체 속성 관련 메서드Object.keys(obj)객체의 자신의 속성(열거 가능한 속성) 키를 배열로 반환상속받은 속성은 제외됨.속성 순서는 추가된 순서를 따름// [문법]Object.keys(객체)const user = { name: "Alice",

u-pub.tistory.com

 

반응형