JavaScript에서 모든 객체는 프로토타입이라는 속성을 갖고 있다. 이 prototype은, 객체가 다른 객체로부터 속성과 메서드를 상속받을 수 있도록 연결하는 일종의 틀이다. (딥다이브에는 슬롯이라고 써있었던 듯) 객체가 만들어질 때 해당 객체는 다른 객체의 속성과 메서드를 "상속"하는 구조를 갖는다.
프로토타입 체인(Prototype Chain)
Javascript는 "프로토타입 기반 상속"을 사용하는 언어로, 객체가 다른 객체의 속성을 상속받기 위해 프로토타입 체인(Prototype Chain)을 형성한다. 프로토타입 체인은, 객체가 특성 속성에 접근하려고 할 때, 해당 객체에서 찾을 수 없으면 프로토타입 객체를 거슬러 올라가며 탐색하는 메커니즘이다.
예를 들어 animal 객체가 있고, 이를 기반으로 dog 객체를 만든다면, dog 객체는 animal 객체의 프로토타입을 통해 animal의 속성과 메서드에 접근할 수 있다.
프로토타입은 객체 간에 메서드와 속성을 공유하기 위해 사용되며,
주요 역할은 다음과 같다.
: 객체가 프로토타입을 통해 속성과 메서드를 상속받으므로, 메모리 낭비를 줄이고 코드의 재사용성을 높인다. 예를 들어, 모든 객체에 같은 메서드를 추가하는 대신, 프로토타입에 추가하면 생성된 모든 인스턴스가 이 메서드를 공유할 수 있다.
: 생성자 한수에 추가된 메서드는 모든 인스턴스가 공유하므로, 효율적으로 메서드를 관리할 수 있다. 예를 들어, Person 생성자 함수의 prototype에 sayHello를 추가하면, 이 생성자를 통해 만든 모든 Person 인스턴스는 sayHello 메서드를 사용할 수 있다.
: 특정 생성자 함수의 프로토타입 객체에, 메서드나 속성을 추가하면 이미 만들어진 객체도 포함한 해당 생성자의 모든 인스턴스가, 이 수정된 메서드나 속성을 사용할 수 있게 된다.
🖥️ javascript
// 생성자 함수 정의
function Person(name) {
this.name = name;
}
// 프로토타입에 메서드 추가
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
// 인스턴스 생성
const person1 = new Person('Alice');
const person2 = new Person('Bob');
// 프로토타입 메서드 호출
person1.sayHello(); // "Hello, my name is Alice"
person2.sayHello(); // "Hello, my name is Bob"
위 코드에서Person 생성자 함수로 생성된 모든 인스턴스는 Person.prototype에 정의된 sayHello 메서드를 공유한다. 각 인스턴스는 메모리에 별도로 sayHello 메서드를 가지지 않고, 프로토타입 체인을 통해 Person.prototype.sayHello를 참조해 사용.
person1 객체에서 sayHello 메서드를 호출한다면, JavaScript는 다음과 같이 속성을 찾는다.
1. 먼저 person1 객체 자체에서 sayHello 메서드를 찾는다.
2. person1 객체에 sayHello가 없으면, person1의 프로토타입인 Person.prototype 객체에서 sayHello를 찾는다.
3. Person.prototype에 sayHello가 존재하므로, 이 메서드를 실행한다.
이런 방식으로 필요할 때만 프로토타입 객체에 접근해 메서드나 속성을 찾고 사용한다.
메모리 효율
모든 인스턴스에 멘서드를 개별적으로 저장할 필요 없이, 프로토타입 객체 하나만 사용해 메모리를 효율적으로 사용한다.
코드 재사용성
모든 객체가 동일한 프로토타입 메서드를 공유하므로, 객체 간에 기능을 일관되게 유지할 수 있다.
__proto__는 각 객체가 가리키는 자신의 프로토타입 객체를 참조하는 속성이다.
❓무슨 소리지? 딥다이브 그림 보면 알 것 같기도
prototype은 생성자 함수의 속성으로, 이 생성자로 생성된 모든 인스턴스 객체가 공유하는 프로토타입 객체를 참조한다.