본문으로 건너뛰기
김신건의 로그

[Javascript] Prototype Chain

· 수정 · 📖 약 1분 · 288자/단어 #javascript #prototype #oop #fundamentals
JS Prototype, JS Prototype Chain, Prototype, 프로토타입, 프로토타입 체인, prototypal inheritance, prototype chain

정의

JavaScript 의 모든 객체는 [[Prototype]] (내부 슬롯) 을 가진다. 속성 lookup 시 자신에게 없으면 prototype chain 을 따라 올라가며 검색.

const animal = { eats: true };
const dog = Object.create(animal);
dog.barks = true;

dog.barks    // true (own)
dog.eats     // true (prototype 에서)

접근

Object.getPrototypeOf(obj)     // [[Prototype]] 반환
Object.setPrototypeOf(obj, p)  // 변경 (성능 주의)
obj.__proto__                   // 비표준 getter (피하기)

함수의 prototype

함수는 prototype property 를 가진다 (객체).

function Foo() {}
Foo.prototype                  // {} (객체)
Foo.prototype.constructor      // Foo

const obj = new Foo();
Object.getPrototypeOf(obj) === Foo.prototype    // true
obj.__proto__ === Foo.prototype                 // true

new Foo() 시 새 객체의 [[Prototype]]Foo.prototype 으로 설정.

class 와의 관계

class Animal {
    eat() { return 'eating'; }
}

class Dog extends Animal {
    bark() { return 'woof'; }
}

const d = new Dog();
d.bark()    // 'woof' (own)
d.eat()     // 'eating' (prototype chain)

내부적으로 같은 prototype chain.

d → Dog.prototype → Animal.prototype → Object.prototype → null

prototype chain 의 끝

Object.getPrototypeOf({}) === Object.prototype       // true
Object.getPrototypeOf(Object.prototype) === null     // true

const clean = Object.create(null);
Object.getPrototypeOf(clean)    // null

Object.create(null)prototype 없는 진짜 깨끗한 객체 (사전처럼 사용).

속성 lookup 순서

const grandparent = { x: 1 };
const parent = Object.create(grandparent);
parent.y = 2;
const child = Object.create(parent);
child.z = 3;

child.z   // 3 (own)
child.y   // 2 (parent)
child.x   // 1 (grandparent)
child.w   // undefined (chain 끝까지 못 찾음)

자신 → prototype → … → null 까지 탐색.

속성 검색 시점

  • 읽기 : chain 전체 검색
  • 쓰기 : 자기 자신에 추가 (chain 변경 안 함)
const parent = { x: 1 };
const child = Object.create(parent);
child.x   // 1 (parent 에서)
child.x = 2;
child.x   // 2 (own, parent 의 x 는 1 그대로)
parent.x  // 1

constructor

function Foo() {}
const obj = new Foo();
obj.constructor === Foo    // true (Foo.prototype.constructor)

[].constructor === Array   // true
'hi'.constructor === String  // true (auto-boxing)

Object 메서드들

메서드의미
Object.hasOwn(obj, key)own property 검사 (Object.hasOwnProperty 대체)
obj.hasOwnProperty(key)같음 (옛 방식)
key in objchain 포함 포함 검사
Object.keys(obj)own enumerable string 키
Object.getOwnPropertyNames(obj)own non-enumerable 포함
Reflect.ownKeys(obj)모든 own (Symbol 포함)
const parent = { x: 1 };
const child = Object.create(parent);
child.y = 2;

'y' in child           // true
'x' in child           // true (chain)
Object.hasOwn(child, 'y')   // true
Object.hasOwn(child, 'x')   // false

Object.keys(child)     // ['y']

class 의 static vs instance

class Foo {
    static staticMethod() { return 'static'; }
    instanceMethod() { return 'instance'; }
}

Foo.staticMethod()           // ✓ (Foo 자체에 있음)
new Foo().staticMethod()      // ❌ (instance 의 prototype 에 없음)

new Foo().instanceMethod()    // ✓ (Foo.prototype 에 있음)
Foo.instanceMethod()          // ❌

함정

1. proto vs prototype

// instance → __proto__ 또는 getPrototypeOf
// function → prototype
function Foo() {}
const f = new Foo();
f.__proto__ === Foo.prototype    // true
f.prototype                       // undefined

2. setPrototypeOf 의 성능

엔진이 prototype chain 을 캐시 / 최적화. 변경하면 deoptimization. 가능하면 Object.create 로 처음부터.

3. arrow function 에는 prototype 없음

const arrow = () => {};
arrow.prototype     // undefined
new arrow()         // ❌ TypeError

생성자로 사용 불가.

4. delete 후 chain 검색

const parent = { x: 1 };
const child = Object.create(parent);
child.x = 2;
delete child.x;
child.x   // 1 (parent 의 x 가 다시 보임)

참고

이 글의 용어 (3개)
[Javascript] Classjavascript
정의 ES6 는 prototype chain 위의 문법 설탕. C++/Java 스타일 OOP 와 닮았지만 내부는 . 구조 상속 super 의 의미 - : 부모 constructo…
[Javascript] Lexical Environmentjavascript
정의 Lexical Environment (어휘적 환경) 는 ECMAScript 명세 (§9.1) 가 정의한 내부 객체. 함수가 호출될 때마다 새로 만들어지며, 이 호출의 변수들…
[Javascript] Objectjavascript
정의 JavaScript 의 는 key-value 쌍의 컬렉션. 거의 모든 non-primitive 값이 객체. 함수, 배열, 정규식도 객체. 생성 접근 수정 / 삭제 Objec…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기