프로토타입이란?
No Filled
자바스크립트에서 객체가 다른 객체의 속성과 메서드를 참조할 수 있게 해주는 링크 메커니즘으로, 클래스 기반 언어의 상속을 구현하는 자바스크립트만의 방식
기본 개념
- 프로토타입은 자바스크립트 객체가 가지고 있는 숨겨진 속성으로 다른 객체를 가리키는 내부 링크
- 모든 객체는
[[Prototype]]이라는 내부 슬롯 소유 - 이를 통해 다른 객체의 속성과 메서드를 상속 가능
등장 배경
- 자바스크립트는 클래스 기반이 아닌 프로토타입 기반 언어로 설계
- 다음과 같은 문제를 해결하기 위해 프로토타입을 도입
- 메모리 효율성: 모든 객체마다 메서드를 복사하지 않고 공유
- 동적 상속: 런타임에 상속 관계를 변경 가능
- 유연한 객체 확장: 기존 객체에 기능을 동적으로 추가
동작 원리
프로토타입 체인 탐색 과정
- 객체의 속성에 접근 시도
- 해당 객체에 속성이 있으면 반환
- 없으면
[[Prototype]]링크를 따라 부모 객체에서 탐색 - 찾을 때까지 또는 null을 만날 때까지 체인을 따라 계속 탐색
관련 개념과 비교
클래스 vs 프로토타입
- 클래스: 설계도를 먼저 만들고 복사 (Java, C++)
- 프로토타입: 객체를 직접 연결하여 공유 (JavaScript)
__proto__ vs prototype
__proto__: 모든 객체가 가진 실제 프로토타입 링크prototype: 함수 객체만 가진 속성, 생성자로 사용될 때 인스 턴스의 proto가 가리킬 객체
예시 코드
// 생성자 함수
function Person(name, age) {
this.name = name
this.age = age
}
// prototype에 메서드 추가
Person.prototype.greet = function () {
return `안녕하세요, 저는 ${this.name}입니다.`
}
Person.prototype.species = 'Human'
// 인스턴스 생성
const john = new Person('John', 30)
const jane = new Person('Jane', 25)
console.log(john.greet()) // "안녕하세요, 저는 John입니다."
console.log(jane.greet()) // "안녕하세요, 저는 Jane입니다."
// 프로토타입 체인 확인
console.log(john.hasOwnProperty('name')) // true (자신의 속성)
console.log(john.hasOwnProperty('greet')) // false (프로토타입 속성)
console.log(john.species) // "Human"
// 프로토타입 관계 확인
console.log(john.__proto__ === Person.prototype) // true
console.log(Person.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__) // null
// 안녕하세요, 저는 John입니다.
// 안녕하세요, 저는 Jane입니다.
// true
// false
// Human
// true
// true
// null프로토타입 체인 비교
// Object.create를 사용한 프로토타입 상속
const animal = {
type: 'Animal',
speak() {
return `${this.name} makes a sound`
},
}
const dog = Object.create(animal)
dog.name = 'Buddy'
dog.bark = function () {
return 'Woof!'
}
console.log(dog.speak()) // "Buddy makes a sound"
console.log(dog.bark()) // "Woof!"
console.log(dog.type) // "Animal" (프로토타입에서 상속)
// 클래스 문법 (내부적으로는 프로토타입 사용)
class Animal {
constructor(name) {
this.name = name
}
speak() {
return `${this.name} makes a sound`
}
}
class Dog extends Animal {
bark() {
return 'Woof!'
}
}
const puppy = new Dog('Max')
console.log(puppy.speak()) // "Max makes a sound"
console.log(puppy.bark()) // "Woof!"
// 두 방식 모두 내부적으로는 프로토타입 체인 사용
console.log(puppy.__proto__ === Dog.prototype) // true헷갈리기 쉬운 부분
__proto__ vs prototype의 정확한 차이
function Car() {}
const myCar = new Car()
// prototype: 생성자 함수의 속성
console.log(Car.prototype) // { constructor: Car }
console.log(myCar.prototype) // undefined (인스턴스는 prototype 없음)
// __proto__: 실제 프로토타입 링크
console.log(myCar.__proto__) // Car.prototype과 같은 객체
console.log(myCar.__proto__ === Car.prototype) // trueprototype: 함수 객체만 가지는 속성, 생성자로 사용될 때 인스턴스가 참조할 프로토타입 객체__proto__: 모든 객체가 가지는 실제 프로토타입 링크,Object.getPrototypeOf()로 접근 권장
오해: 프로토타입은 복사다
// ❌ 잘못된 이해: 프로토타입은 복사되지 않습니다
Person.prototype.species = 'Human'
const person1 = new Person('Alice', 20)
// 프로토타입 수정 시 모든 인스턴스에 반영
Person.prototype.species = 'Homo Sapiens'
console.log(person1.species) // "Homo Sapiens" (복사가 아니라 참조!)프로토타입 체인과 속성 검색
function Parent() {}
Parent.prototype.value = 10
function Child() {}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.value = 20 // 오버라이딩
const child = new Child()
child.value = 30 // 인스턴스 속성
console.log(child.value) // 30 (인스턴스 속성)
delete child.value
console.log(child.value) // 20 (Child.prototype.value)
delete Child.prototype.value
console.log(child.value) // 10 (Parent.prototype.value)프로토타입 체인의 끝은?
Object.prototype.__proto__는null- 모든 객체의 프로토타입 체인은 결국
Object.prototype에서 끝남
개념 정리
프로토타입이 무엇인가요?
프로토타입은 자바스크립트 객체가 다른 객체로부터 속성과 메서드를 상속받을 수 있게 해주는 메커니즘입니다.
자바스크립트는 클래스 기반이 아닌 프로토타입 기반 언어입니다.
모든 객체는 내부적으로 [[Prototype]]이라는 숨겨진 링크를 가지고 있으며,
이를 통해 다른 객체를 참조합니다.
이러한 연결 고리를 '프로토타입 체인'이라고 합니다.
작동 방식은 객체의 속성에 접근할 때 해당 속성이 객체 자체에 없으면,
자바스크립트 엔진은 프로토타입 체인을 따라 상위 객체에서 해당 속성을 찾습니다.
이 과정은 속성을 찾거나 체인의 끝인 null을 만날 때까지 계속됩니다.
예를 들어 생성자 함수로 객체를 만들 때 new 키워드를 사용하면,
생성된 인스턴스의 [[Prototype]]은 생성자 함수의 prototype 속성을 가리킵니다.
이를 통해 모 든 인스턴스가 메서드를 공유할 수 있어 메모리를 효율적으로 사용할 수 있습니다.
프로토타입을 이해하는 것은 자바스크립트의 상속 메커니즘을 이해하는 핵심이며, ES6의 클래스 문법도 내부적으로는 프로토타입을 사용합니다.
핵심 문장
- 프로토타입은 자바스크립트 객체 간의 상속을 구현하는 메커니즘
- 모든 객체는 다른 객체를 참조하는 내부 링크 가지며, 속성을 찾을 때 이 체인을 따라 상위 객체를 탐색
- 생성자 함수의
prototype속성에 메서드를 정의하면 모든 인스턴스가 이를 공유하여 메모리를 효율적으로 사용 가능