class design pattern
Singlton, factory, iterator, observer
Javascript Classes
Javascript Mixins
其他语言中类表现出来的都是复制行为,因此 JavaScript 开发者也想出了一个方法来 模拟类的复制行为,这个方法就是混入。接下来我们会看到两种类型的混入:显式和隐式。
- 显式混入 ```javascript 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( “Turning on my engine.” ); }, drive: function() { console.log(“vehicle drive “,this); this.ignition(); console.log( “Steering and moving forward!” ); } };
var Car = mixin( Vehicle, { wheels: 4, drive: function() { console.log(“car drive “ ,this); Vehicle.drive.call( this ); //显式多态 console.log( “turn on on all “ + this.engines + “ engines!” ); console.log( “Rolling on all “ + this.wheels + “ wheels!” ); } });
Car.drive();
输出为
> car drive Object { wheels: 4, drive: Car<.drive(), engines: 1, ignition: Vehicle.ignition() }
> vehicle drive Object { wheels: 4, drive: Car<.drive(), engines: 1, ignition: Vehicle.ignition() }
> Turning on my engine.
> Steering and moving forward!
> turn on on all 1 engines!
> Rolling on all 4 wheels!
可见,`Car`中具有了`Vehicle`的属性和函数副本。`Car`复制的只是函数的引用,即*浅复制*。由于 Car 和 Vehicle 中都有 drive() 函数,为了指明调用对象,我们必须使用绝对(而不是相对)引 用。我们通过名称显式指定 Vehicle 对象并调用它的 drive() 函数。我们将`Vehicle.drive.call( this );`称为显式多态。
> Note: 此处正是因为Car和Vehcle都有drive function
2. 隐式混入
3. 寄生继承
Douglas Crockford 推广了一种混入模式叫做“寄生继承”,同时具有显式和隐式特征。以下面例子为例:
```javascript
function Vehicle() {
this.engines = 1;
}
Vehicle.prototype.ignition = function() {
console.log('ignition',this);
console.log( "Turning on my engine." );
};
Vehicle.prototype.drive = function() {
console.log('drive',this);
this.ignition();
console.log( "Steering and moving forward!" );
};
//“寄生类”Car
function Car() {
// 首先,car 是一个 Vehicle
var car = new Vehicle();
// 接着我们对 car 进行定制
car.wheels = 4;
// 保存到 Vehicle::drive() 的特殊引用
var vehDrive = car.drive;
// 重写 Vehicle::drive()
car.drive = function() {
vehDrive.call( this );
console.log("Rolling on all " + this.wheels + " wheels!");
}
return car;
}
var myCar = new Car();
myCar.drive();
- 首先我们创建了一个Vehicle的父类object; ```javascript function Vehicle() { this.engines = 1; }
Vehicle.prototype.ignition = function() { console.log(‘ignition’,this); console.log( “Turning on my engine.” ); };
Vehicle.prototype.drive = function() { console.log(‘drive’,this); this.ignition(); console.log( “Steering and moving forward!” ); };
2. 然后混入子类对象的一些定义,或者继承父类object的属性,或者重新定义。
```javascript
//“寄生类”Car
function Car() {
// 首先,car 是一个 Vehicle
var car = new Vehicle(); //继承父类
// 接着我们对 car 进行定制
car.wheels = 4;
// 保存到 Vehicle::drive() 的特殊引用
var vehDrive = car.drive;
// 重写 Vehicle::drive()
car.drive = function() {
vehDrive.call( this );//显式继承
console.log("Rolling on all " + this.wheels + " wheels!");
}
return car;
}
- 然后利用这个复合对象构建实例。 ```javascript
var myCar = new Car();
隐性继承
```javascript
var Something = {
cool: function() {
this.greeting = "Hello World";、
this.count = this.count ? this.count + 1 : 1;
}
};
Something.cool();
console.log(Something.greeting); // "Hello World"
console.log(Something.count) // 1
var Another = {
cool: function() {
Something.cool.call(this);
}
};
Another.cool();
console.log(Another.greeting);
console.lgo(Another.count);