Bami 2022. 9. 14. 11:58
728x90
반응형

Prototype 패턴

동일 타입의 여러 객체들이 프로퍼티를 공유한다

 


 

 

📜 원문: patterns.dev - prototype pattern

📜 번역: https://patterns-dev-kr.github.io/design-patterns/prototype-pattern/

 

Prototype 패턴은 동일 타입의 여러 객체들이 프로퍼티를 공유할 때 유용하게 사용합니다.

Prototype은 JavaScript 객체의 기본 속성이므로 Prototype 체인을 활용할 수 있죠.


하나의 앱을 만들 때 동일한 타입의 여러 객체를 만들어내곤 합니다. ES6 의 클래스의 여러 인스턴스를 만들어 낼 때 유용하게 사용할 수 있죠.

 

여러 강아지 클래스를 만들어 보겠습니다. 예제에서 강아지는 이름을 가지고 있고. 짖을 수 있습니다.

 

class Dog {
  constructor(name) {
    this.name = name
  }

  bark() {
    return `Woof!`
  }
}

const dog1 = new Dog('Daisy')
const dog2 = new Dog('Max')
const dog3 = new Dog('Spot')

Dog 클래스의 생성자에서는 name 프로퍼티를 가지고 있고 클래스 자체적으로는 bark 프로퍼티를 가지고 있습니다. 

ES6클래스를 사용하면 모든 프로퍼티는 클래스 자체에 선언되며 위의 코드에서 bark 는 자동으로 prototype 에 추가됩니다.


생성자의 prototype 프로퍼티 혹은 생성된 인스턴스의 __proto__ 프로퍼티를 통해 Prototype 객체를 확인할 수 있습니다.

 

💡 역자 주: __proto__ 는 비 표준이다. Object.getPrototypeOf는 표준이므로 이를 사용한다.
console.log(Dog.prototype)
// constructor: ƒ Dog(name, breed) bark: ƒ bark()

console.log(dog1.__proto__)
// constructor: ƒ Dog(name, breed) bark: ƒ bark()

어떤 인스턴스던 __proto__ 의 값은 Prototype 객체를 가리킵니다. 객체에 없는 프로퍼티에 접근하려 하는 경우 JavaScript는 이 프로퍼티가 나타날때 까지 prototype chain 을 거슬러 올라갑니다.

 

Prototype 패턴은 객체들이 같은 프로퍼티를 가져야 하는 경우 유용하게 쓰일 수 있습니다. 중복된 프로퍼티들이 존재하는 객체를 매번 생성하기 보다, Prototype에 프로퍼티를 추가하면 모든 인스턴스들이 Prototype 객체를 활용할 수 있습니다.

 

모든 인스턴스들이 Prototype에 접근 가능하기 때문에. 인스턴스를 만든 뒤에도 Prototype에 프로퍼티를 추가할 수 있습니다.

 

예제에서 강아지는 짖기만 가능했지만 놀 수도 있게 구현해 보죠. Prototype 객체에 play 프로퍼티를 추가하여 가능합니다.

 

Prototype “체인” 단어처럼 Prototype은 한 단계 이상도 존재할 수 있습니다. 지금까지 어떤 인스턴스의 proto 속성에 대해서 이야기 했지만 사실 Prototype 객체 자체도 proto속성을 가질 수 있습니다.

 

이제 다른 타입의 강아지를 만들어 보죠. 이 강아지는 Dog의 속성을 모두 가지고 있지만 하늘을 날 수 있습니다.

이 슈퍼 강아지는 Dog 클래스를 상속받아 fly 메서드를 구현하면 됩니다.

 

class SuperDog extends Dog {
  constructor(name) {
    super(name)
  }

  fly() {
    return 'Flying!'
  }
}

아래 예제에서는 Daisy 라는 강아지를 만들고 짖거나 하늘을 날 수 있게 하고 있습니다.

 

SuperDog 는 Dog 를 상속했습니다. 따라서 인스턴스 dog1 은 bark 메서드도 호출 할 수 있다. SuperDog 의 Prototype 객체의 proto 는 Dot.prototype을 가리키고 있습니다.

 

Prototype 체인이라 불리우는 이유가 명확해졌을것이다. 현재 객체에 없는 프로퍼티에 접근하려 하는 경우 JavaScript는 같은 이름의 프로퍼티를 찾을때까지 재귀적으로 객체의 proto 를 따라 거슬러 올라가게 됩니다.


Object.create

Object.create 메서드는 Prototype으로 쓰일 객체를 인자로 받아 새로운 객체를 만들어냅니다.

const dog = {
  bark() {
    return `Woof!`
  },
}

const pet1 = Object.create(dog)

pet1 자체적으로는 아무런 프로퍼티도 없지만 dog 객체를 Prototype으로 사용하기 때문에 bark 메서드를 사용할 수 있습니다.

 

Object.create 는 단순히 객체가 다른 객체로부터 프로퍼티를 상속받을 수 있게 해 줍니다. 실행 결과로 생성되는 객체는

Prototype 체인으로 인해 인자로 넘어갔던 객체의 프로퍼티를 활용할 수 있는 것이죠.


Prototype 패턴은 어떤 객체가 다른 객체의 프로퍼티를 상속받을 수 있도록 해 줍니다.

Prototype 체인을 통해 해당 객체에 프로퍼티가 직접 선언되어 있지 않아도 되므로 메서드 중복을 줄일 수 있고 이는 메모리 절약으로 이어집니다.

 

참조

728x90
반응형