Instantiation Patterns
인스턴스란 클래스 등을 이용하여 만들어진 구체적인 실체이다. 클래스가 설계도라면 인스턴스는 설계도를 이용하여 만들어진 실제 제품이라고 볼 수 있다. 그렇다면 객체는 인스턴스일까? 객체는 소프트웨어 세계에 구현할 대상으로 소프트웨어 관점에서는 개념적인 것(Concept)이다. 따라서 클래스로 만들어진 구체적인 실체를 인스턴스라고 부르는 것이 더 정확한 표현이다. 하지만 개념적으로 인스턴스는 객체에 포함되므로 클래스로 만들어진 구체적인 실체를 객체라 부르는 것도 틀린 말이 아니다.
JavaScript에서 인스턴스를 만드는 방법은 Class 외에 4가지 방법이나 존재한다.
1. Functional
const Plant = function(height){
const someInstance = {};
someInstance.food = 'water';
someInstance.height = height;
someInstance.grow = function() {
this.height += 1;
}
return someInstance;
}
let plant1 = Plant(0);
let plant2 = Plant(1);
plant1.grow();
인스턴스를 생성하기위한 함수를 이용하는 가장 단순한 방식이다. 함수가 호출되었을 때 함수 내부에서 빈 객체를 만든 뒤 속성과 값을 더해주는 것이다. 함수를 호출할 때마다 새로운 객체가 생기고(새로운 메모리가 할당) 같은 속성과 값을 할당해주므로 Plant함수를 통해 리턴되는 객체는 같은 틀에서 찍어낸 것처럼 같은 형태를 띄고있을 것이다.
위 방법은 메모리효율 측면에서 단점이 있다. Plant의 food 속성과 grow 메소드는 모든 Plant 인스턴스가 항상 동일한 값을 갖고있기 때문에 인스턴스들이 food와 grow를 공유하는 것이 메모리적으로 효율적이다. 그러나 위와 같이 구현한 경우 인스턴스를 생성할 때마다 새로운 객체의 새로운 메모리에 food속성과 grow 메소드를 저장하고 있으므로 plant1과 plant2의 food와 grow가 각자 다른 곳에 저장되어 총 6개의 메모리를 사용하게 된다.
2. Function Shared
const extend = function(to, from) { //객체에 속성 추가
for (var key in from){
to[key] = from[key];
}
}
const someObj = {}; //추가할 속성
someObj.food = 'water';
someObj.grow = function(){
this.height += 1;
};
const Plant = function(height){
const someInstance = {
height: height
};
extend(someInstance, someObj);
extend(someInstance, someObj);
return someInstance;
}
let plant1 = Plant(0);
let plant2 = Plant(1);
plant1.grow();
let plant1 = Plant(0);
let plant2 = Plant(1);
plant1.grow();
위의 방법으로 만든다면 항상 공통된 값을 갖는 속성과 메소드를 하나의 메모리에 저장하고 모든 인스턴스가 이를 공유할 수 있다. 그러나 이 방법은 코드가 비교적 복잡하고 길어져 가독성이 떨어지는 단점이 있다.
3. Prototypal
var someObj = {};
someObj.food = 'water'
someObj.grow = function(){
this.height += 1;
};
var Plant = function(height){
var someInstance= Object.create(someObj);
someInstance.height = height
return someInstance;
}
var plant1 = Plant(0);
var plant2 = Plant(1);
plant1.grow();
위 방법은 prototype을 이용한 방법이다. Object.create() 함수는 특정 객체를 프로토타입으로 하는 객체를 생성해주는 함수이다. 즉, food와 grow를 갖고있는 someObj를 프로토타입으로 하는 객체를 만들고 hight 속성을 추가하는 방법이다.
4. Psedoclassical
var Plant = function(height){
this.height = height;
}
Plant.prototype.grow = function(){
this.height += 1;
};
Plant.prototype.food = 'water';
var plant1 = new Plant(0);
var plant2 = new Plant(1);
plant1.grow();
위 방법 역시 prototype을 이용한 방법이다. 이 때는 Object.create()를 사용하지 않고 바로 Plant 함수의 prototype을 수정한다. 또한 Plant 함수에서 객체를 리턴하는 것이 아니라 new operator를 통해 인스턴스를 생성하고 있다.
참고 사이트