클래스 지향 디자인패턴
new나 instanceof 등 클래스와 비슷하게 생긴 구문도 있고 ES6부터는 아예 class라는 키워드가 명세에 정식적으로 추가됐지만, 사실 클래스는 없다.new 키워드를 앞에 붙여 생성자를 호출한다.super 키워드를 사용한다.function mixin(sourceObj, targetObj) {
for (var key in sourceObj) {
if (!key in targetObj) {
targetObj[key] = sourceObj[key];
}
}
return targetObj;
}
var Vehicle = {
engines: 1,
ignition: function() {
console.log("엔진을 켠다.")
},
drive: function() {
this.ignition();
console.log("방향을 맞추고 앞으로 간다!");
}
};
var Car = mixin(Vehicle, {
wheels: 4,
drive: function() {
Vehicle.drive.call(this);
console.log(this.wheels + "개의 바퀴로 굴러간다!");
}
});
Car에는 Vehicle에서 복사한 프로퍼티와 함수 사본이 있다.Car에는 이미 자체 drive 프로퍼티가 있으므로 이 프로퍼티 레퍼런스는 오버라이드되지 않는다.Vehicle.drive.call(this)와 같은 코드를 명시적 의사다형성이라 부른다.drive()란 이름의 함수가 Vehicle과 Car 양쪽에 모두 있을 때 이 둘을 구별해서 호출하려면 절대적인 레퍼런스를 이용할 수밖에 없고 그래서 명시적으로 Vehicle 객체의 이름을 지정하여 drive() 함수를 호출한 것이다.Vehicle.drive()로 함수를 호출하면 this는 Car 객체가 아닌 Vehicle 객체와 바인딩 되는데, 이때문에 .call(this)를 붙여 drive()를 Car 객체의 콘텍스트로 실행하도록 강제한 것이다.var Something = {
cool: function() {
this.greeting = "Hello World";
this.count = this.count ? this.count + 1 : 1;
}
};
Something.cool();
Something.greeting();
Something.count();
var Another = {
cool: function() {
Something.cool.call(this);
}
};
Another.cool();
Another.greeting();
Another.count;
Someting.cool.call(this)를 하면 Something.cool() 함수를 본질적으로 빌려와서 Another 콘텍스트로 호출한다.Something.call()의 할당은 Something이 아닌 Another다. 따라서 Something의 작동을 Another와 섞은 셈이다.this 재바인딩을 십분 활용한 이런 유형의 테크닉은 Something.cool.call(this)같은 호출이 상대적 레퍼런스가 되지 않아 불안정하므로 사용할 때 신중히 해야한다.