Prototype 패턴
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 객체를 확인할 수 있다.
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 체인을 통해 해당 객체에 프로퍼티가 직접 선언되어 있지 않아도 되므로 메서드 중복을 줄일 수 있고 이는 메모리 절약으로 이어진다.