Yuming Ren Curious and Learning 平平无奇

Javascript OOD Design

2017-09-17
yuming

class design pattern

Singlton, factory, iterator, observer

Javascript Classes

Javascript Mixins

其他语言中类表现出来的都是复制行为,因此 JavaScript 开发者也想出了一个方法来 模拟类的复制行为,这个方法就是混入。接下来我们会看到两种类型的混入:显式和隐式。

  1. 显式混入 ```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();
  1. 首先我们创建了一个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;
}
  1. 然后利用这个复合对象构建实例。 ```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);



上一篇 咖啡知识入门

Comments

Content