자바스크립트 프로토타입(Prototype)

이일우·2023년 3월 15일

공부하기

목록 보기
16/42

프로토타입

자바스크립트는 프로토타입 기반 언어 입니다. 프로토타입은 객체의 원형을 의미하며, 객체가 생성될 때 상속받은 프로퍼티와 메서드를 가지고 있습니다.
인스턴스 객체가 생성자 함수의 프로토타입을 상속받아 부모의 메서드를 사용 할 수 있습니다.

자바스크립트에서 모든 객체는 다른 객체를 프로토타입으로 가지고 있습니다. 프로토타입은 객체가 생성될 때 결정되며, 생성된 객체는 프로토타입의 속성과 메서드를 상속받습니다.

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의 인스턴스인 dogAnimalspeak() 메서드를 사용할 수 있습니다.

.prototype

자바스크립트에서 함수는 객체이며, 모든 함수는 .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

자바스크립트의 모든 객체는 .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.constructorDog 함수를 가리킵니다. 이렇게 객체의 프로토타입에 정의된 .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

https://www.nextree.co.kr/p7323/

0개의 댓글