你不知道的JavaScript(上)this和对象原型(三)

第四章  混核对象“类”

1、理论

面向对象编程强调的是数据和操作数据的行为本质上是互相关联的。实例化,继承,多态性

javascript中只有对象,并不存在可以被实例化的“类”。一个对象并不会被复制到其他对象,他们会被关联起来,由于其他语言中类表现出来的都是复制行为,因此js开发者也想出一个方法来模拟类的复制行为——混入。混入有两种类型:显式和隐式。

2、显式混入

 1 // 非常简单的 mixin(..) 例子 :
 2 function mixin( sourceObj, targetObj ) {
 3 for (var key in sourceObj) {
 4 // 只会在不存在的情况下复制
 5 if (!(key in targetObj)) {
 6 targetObj[key] = sourceObj[key];
 7 }
 8 }
 9 return targetObj;
10 }
11 var Vehicle = {
12 engines: 1,
13 ignition: function() {
14 console.log( "Turning on my engine." );
15 },
16 drive: function() {
17 this.ignition();
18 console.log( "Steering and moving forward!" );
19 }
20 };
21 var Car = mixin( Vehicle, {
22 wheels: 4,
23 drive: function() {
24 Vehicle.drive.call( this );
25 console.log(
26 "Rolling on all " + this.wheels + " wheels!"
27 );
28 }
29 } );

注意:

我们处理的已经不再是类了,因为在 JavaScript 中不存在类,Vehicle 和 Car 都是对象,供我们分别进行复制和粘贴。

 Vehicle.drive.call( this ) 。这就是我所说的显式多态。

由于 Car 和Vehicle 中都有 drive() 函数,为了指明调用对象,我们必须使用绝对(而不是相对)引用。我们通过名称显式指定 Vehicle 对象并调用它的 drive() 函数。

但是如果直接执行 Vehicle.drive() ,函数调用中的 this 会被绑定到 Vehicle 对象而不是Car 对象(参见第 2 章),这并不是我们想要的。因此,我们会使用 .call(this) 来确保 drive() 在 Car 对象的上下文中执行。

显示混入模式的另一种变体“寄生继承”,既是显示也是隐式。

// “传统的 JavaScript 类”Vehicle
function Vehicle() {
this.engines = 1;
}
Vehicle.prototype.ignition = function() {
console.log( "Turning on my engine." );
};
Vehicle.prototype.drive = function() {
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();
// 发动引擎。
// 手握方向盘!
// 全速前进!

 总的来说,不推荐js模拟类。

 

原文地址:https://www.cnblogs.com/chorkiu/p/10114139.html