자바스크립트는 프로토타입 기반 언어 입니다. 프로토타입은 객체의 원형을 의미하며, 객체가 생성될 때 상속받은 프로퍼티와 메서드를 가지고 있습니다.
인스턴스 객체가 생성자 함수의 프로토타입을 상속받아 부모의 메서드를 사용 할 수 있습니다.
자바스크립트에서 모든 객체는 다른 객체를 프로토타입으로 가지고 있습니다. 프로토타입은 객체가 생성될 때 결정되며, 생성된 객체는 프로토타입의 속성과 메서드를 상속받습니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Max');
dog.speak(); // Max barks.
위 예제에서 Dog 클래스는 Animal 클래스를 상속받습니다. 따라서 Dog의 인스턴스인 dog는 Animal의 speak() 메서드를 사용할 수 있습니다.
자바스크립트에서 함수는 객체이며, 모든 함수는 .prototype 속성을 가지고 있습니다. 하지만 .prototype속성은 생성자 함수에서만 사용할 수 있는 속성입니다. 생성자 함수를 통해 생성되는 인스턴스들이 해당 프로토타입 객체를 상속받도록 하는데 사용됩니다.
자바스크립트에서 생성자 함수는 클래스 또는 일반 함수를 이용하여 정의할 수 있습니다. 생성자 함수의 경우, .prototype 속성은 기본적으로 생성자 함수와 연관된 프로토타입 객체를 참조하도록 설정됩니다. 이 프로토타입 객체는 생성자 함수를 사용하여 생성된 인스턴스들이 공유하게 됩니다.
일반 객체에서는 .prototype 속성이 없으며, 프로토타입을 확인하려면 Object.getPrototypeOf() 메서드를 사용해야 합니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
console.log(Animal.prototype); // Animal {speak: ƒ, constructor: ƒ}
자바스크립트의 모든 객체는 .constructor라는 속성을 가지고 있습니다. 이 속성은 객체를 생성한 생성자 함수를 참조합니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Max');
console.log(dog.constructor); // class Dog { ... }
console.log(dog.constructor === Dog); // true
위 예제에서 dog 객체의 .constructor 속성은 Dog 클래스를 참조하고 있습니다. 이를 통해 dog 객체가 어떤 클래스로부터 생성되었는지 알 수 있습니다.
.constructor 속성은 객체의 프로토타입에 정의되어 있습니다. 예를 들어, Dog.prototype.constructor는 Dog 함수를 가리킵니다. 이렇게 객체의 프로토타입에 정의된 .constructor 속성을 통해, 객체는 자신이 어떤 생성자 함수로 생성되었는지 알 수 있습니다.
__proto__와 getPrototypeOf객체가 생성될 때 해당 객체의 프로토타입을 설정하는 __proto__ 속성이 자동으로 생성됩니다. 이 속성은 객체의 생성자 함수의 prototype 속성을 참조합니다.
__proto__ 속성 대신 Object.getPrototypeOf() 메서드를 사용해 객체의 프로토타입을 가져올 수도 있습니다.
const dog = new Dog('Max');
console.log(dog.__proto__ === Dog.prototype); // true
console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true
위 예제에서 dog 객체의 프로토타입은 Dog.prototype입니다. __proto__ 속성과 Object.getPrototypeOf() 메서드를 사용해 dog 객체의 프로토타입에 접근했을 때, 둘 다 Dog.prototype과 같다는 것을 확인할 수 있습니다.
주의사항
모든 자바스크립트 객체는 __proto__ 속성을 통해 자신의 프로토타입에 접근할 수 있습니다. 하지만 __proto__는 권장되지 않는 방식입니다. 이는 __proto__가 표준이 아니며, 브라우저 호환성 문제가 있기 때문입니다. 대신 Object.getPrototypeOf() 메서드를 사용하는 것이 좋습니다.
프로토타입 체인은 자바스크립트에서 객체의 상속을 구현하는 메커니즘입니다. 객체의 프로토타입은 다른 프로토타입을 가질 수 있으며, 이런 관계가 연쇄적으로 이어진 것을 프로토타입 체인이라고 합니다. 객체에서 속성이나 메서드를 참조할 때, 자바스크립트 엔진은 프로토타입 체인을 따라 올라가며 해당 속성이나 메서드를 찾습니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Max');
dog.speak(); // Max barks.
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true
위 예제에서 Dog 클래스는 Animal 클래스를 상속받고 있으며, Animal 클래스는 Object 클래스를 상속받습니다. 따라서 dog 객체의 프로토타입 체인은 Dog.prototype -> Animal.prototype -> Object.prototype 순서로 구성되어 있습니다. 이러한 프로토타입 체인을 통해 객체는 상위 프로토타입의 속성과 메서드에 접근할 수 있습니다.
프로토타입은 객체 지향 프로그래밍의 핵심 개념으로, 객체의 상속을 구현하는 데 사용됩니다. 프로토타입 체인을 이해하면 객체 간의 상속 관계를 더 잘 파악할 수 있습니다.
프로토타입에 대한 코드와 간략한 그림
class Dog{
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Max');
dog.speak() // 'Max barks'

https://velog.io/@nasowoo/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4Instance
https://www.youtube.com/watch?v=wUgmzvExL_E&ab_channel=%EC%BD%94%EB%94%A9%EC%95%A0%ED%94%8C
https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes