반응형
프로토타입(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)이라고 부름 - 프로토타입 체인은 속성 탐색 순서를 결정함
프로퍼티 탐색 시 프로토타입 체인 확인
객체에서 어떤 프로퍼티를 찾을 때, 자바스크립트는 이렇게 탐색
- 자기 자신의 프로퍼티를 먼저 확인
- 없다면 [[Prototype]]이 가리키는 부모 객체 확인
- 부모에도 없다면 그 부모의 부모 확인
- 최상위 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
반응형
'JS > Javascript' 카테고리의 다른 글
[javascript] 배열 1 / 배열(Array) 정의, 배열 인덱스, 배열 길이 (0) | 2025.09.04 |
---|---|
[javascript] 메서드 체이닝(Method Chaining) (0) | 2025.09.03 |
[javascript] 객체 8 / 객체에서의 this (0) | 2025.09.03 |
[javascript] 객체 7 / 객체 내장 메서드 (0) | 2025.09.02 |
[javascript] 객체 6 / 객체와 참조 복사 (원시값, 값 복사, 참조 복사, 얕은 복사, 깊은 복사) (0) | 2025.09.02 |