javascript设计模式——混入模式
2026-04-16 03:24:39
225
分类:javascript归档
为什么要有混入模式(Mixin)
在继承或者实例化时,JS的对象机智并不会自动执行复制行为。简单地说,JS中只有对象,并不存在可以被实例化的类。由于在其他语言中类表现出来的都是复制行为,因此JS的开发者们想出一种模拟类的行为,这个方法就是混入。
定义
Mixin是掺合,混合,糅合的意思,就是将一个对象的一个或多个(或全部)属性(或方法)复制到另外一个对象,Mixin有的是对对象的操作,有的是对类的操作。
注意这个继承还是有区别的。js是一种只支持单继承的语言,毕竟一个对象只有一个原型,如果想实现多继承,那就简单暴力的把需要继承的父类的所有属性都拷贝到子类上,就是使用mixin啦。
特点
Mixin模式可以实现多重继承,可以把Mixin对象当做一个个零件仓库,可以直接把零件仓库里的零件给现有对象装上,能够方便地复用代码、增强现有对象。
对象合并
下面是一个简单的对象递归合并覆盖。
/**
* 对象递归合并覆盖(相比比$.extend()未实现多参数)
* @param {*} target 目标对象
* @param {*] source 拷贝对象
* @param {boolean} overlay 是否覆盖
* @returns {*} target
*/
function assign(target, source, overlay) {
for (let key in target) {
if (typeof target[key] === 'object' && overlay) {
source[key] = apiUtil.assign(target[key], source[key], overlay);
}
}
Object.assign(target, source);//Object.assign()未多级合并,所以使用递归实现
return target;
},示例
var obj1 = {
a: 1,
b: {
b1: 1,
b2: 2
},
c: 3
}
var obj2 = {
a: 'a',
b: {
b2: 'b2',
b3: 'b3'
}
}
assign(obj1, obj2, true);
console.log(obj1)对象的方法复制
比如先创建一个包含各种通用方法的类,然后让其它类扩充于它。这个包含通用方法的类就叫掺元类。多数时候它不会直接实例化或调用,而是作为其它类的模板用于扩充。
/**
* 混入模式
* @param {*} target 目标对象
* @param {*] source 拷贝对象
* @param {boolean} overlay 是否覆盖
* @returns target
*/
function mimix(target,source,overlay) {
target = 'prototype' in target ? target.prototype : target;
source = 'prototype' in source ? source.prototype : source;
for (var key in source) {
if (source.hasOwnProperty(key) && (overlay ? source[key] != null : target[key] == null)) {
target[key] = source[key];
}
}
return target;
}示例
function Tool1() {
this.name = '工具1';
}
Tool1.prototype.fun1 = function () {
console.log('使用工具1');
};
function Tool2() {
this.name = '工具2';
}
Tool2.prototype.fun2 = function () {
console.log('使用工具2');
};
function Tool() {
this.name='工具';
};
Tool.prototype.execute = function () {
console.log('使用工具');
};
augment(Tool,Tool1,true);
augment(Tool,Tool2,true);
var tool=new Tool();
console.log(tool);总结
Mixin是JavaScript中用的最普遍的模式,几乎所有流行类库都会有Mixin的实现,只是叫法不一样,比如 jQuery的extend,可以浅拷贝和深拷贝。
缺点
Mixin是一种很灵活的代码复用方式,但把功能注入原型对象会导致原型污染和函数来源方面的不确定性,在大型系统中可能是一个严重的问题。可以通过详细的文档来解决函数来源不确定的问题,但原型污染是不可避免的。
参考: