深入理解javascript混合对象“类“(二)

前言

      上一章我们介绍了有关传统面向类的设计模式,实例化,多态,继承,我们了解到这些并没在js中得到应用,js有自己的方式来实现上面的内容,这一章我们将细致地展开js是怎么实现自己的混合对象“类“的

正文

      在继承或者实例化时,JavaScript 的对象机制并不会自动执行复制行为。简单来说,JavaScript 中只有对象,并不存在可以被实例化的“类”。一个对象并不会被复制到其他对象,它们会被关联起来。由于在其他语言中类表现出来的都是复制行为,因此 JavaScript 开发者也想出了一个方法来。模拟类的复制行为,这个方法就是混入。接下来我们会看到两种类型的混入:显式和隐式。

显式混入

      首先我们来回顾一下之前提到的 Vehicle 和 Car。由于 JavaScript 不会自动实现 Vehicle到 Car 的复制行为,所以我们需要手动实现复制功能。

// 非常简单的 mixin(..) 例子 :
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() {
		this.ignition();
		console.log( "Steering and moving forward!" );
	}
};
var Car = mixin( Vehicle, {
	wheels: 4,
	drive: function() {
	Vehicle.drive.call( this );
	console.log("Rolling on all " + this.wheels + " wheels!");
	}
} );

      Vehicle.drive.call( this )。这就是我所说的显式多态。在之前的伪代码中对应的语句是inherited:drive(),我们称之为相对多态。JavaScript并没有相对多态的机制。所以,由于 Car 和Vehicle 中都有 drive() 函数,为了指明调用对象,我们必须使用绝对(而不是相对)引用。我们通过名称显式指定 Vehicle 对象并调用它的 drive() 函数。但是如果直接执行 Vehicle.drive(),函数调用中的 this 会被绑定到 Vehicle 对象而不是Car 对象,这并不是我们想要的。因此,我们会使用 .call(this)来确保 drive() 在 Car 对象的上下文中执行。

隐式混入

var Something = {
	cool: function() {
		this.greeting = "Hello World";
		this.count = this.count ? this.count + 1 : 1;
	}
};
Something.cool();
Something.greeting; // "Hello World"
Something.count; // 1
var Another = {
	cool: function() {
		// 隐式把 Something 混入 Another
		Something.cool.call( this );
	}
};
Another.cool();
Another.greeting; // "Hello World"
Another.count; // 1(count 不是共享状态)

      通过在构造函数调用或者方法调用中使用 Something.cool.call( this ),我们实际上“借用”了函数 Something.cool() 并在 Another 的上下文中调用了它。最终的结果是 Something.cool() 中的赋值操作都会应用在 Another 对象上而不是Something 对象上。

小结

      类是一种设计模式。许多语言提供了对于面向类软件设计的原生语法。JavaScript 也有类似的语法,但是和其他语言中的类完全不同。类意味着复制。传统的类被实例化时,它的行为会被复制到实例中。类被继承时,行为也会被复制到子类中。JavaScript 并不会(像类那样)自动创建对象的副本。在JavaScript 中模拟类是得不偿失的,虽然能解决当前的问题,但是可能会埋下更多的隐患。
      小伙伴们今天的学习就到这里了,如果觉得本文对你有帮助的话,欢迎转发,评论,收藏,点赞!!!
      每天学习进步一点点,就是领先的开始。如果想继续提高,欢迎关注我,或者关注公众号”祯民讲前端“。大量前端技术文章,面试资料,技巧等助你更进一步!
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值