这篇文章主要介绍“JavaScript中的Mixin是什么”,在日常操作中,相信很多人在JavaScript中的Mixin是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaScript中的Mixin是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
类的出现最终使
JavaScript非常容易使用继承语法,
JavaScript类比大多数人意识到的更强大,它是构建真正的
mixins的良好基础。
什么是 Mixin
在
JavaScript中,把不同类的行为集中到一个类是一种常见的模式,虽然
ES6没有显示支持多类继承,但通过现有特性可以轻松地模拟这种行为。
Object.assign()方法是为了混入对象行为而设计的,只有在需要混入类的行为时才有必要自己实现混入表达式,如果只是需要混入多个对象的属性,那么使用
Object.assign()就可以了。
在集成或者实例化时,
JavaScript的对象机制并不会自动执行复制行为,简单来说,在
JavaScript中只有对象,并不存在可以被实例化的类,一个对象并不会被复制到其他对象,它们会被关联起来。
在其他语言中类表现出来的都是复制行为,因此
JavaScript开发者也想出了一个方法来模拟类的复制行为,这个方法就是混入。
那么在接下来的内容中我们会看到两种类型的混入,它们分别是显示混入和隐式混入。
显示混入
首先我们举一个简单的例子,在这里我们实现一个
mixin(...)函数,这个功能在许多库和框架中被称为
extend,具体代码如下所示:
function mixin(source, target) { for (const key in source) { if (!(key in target)) target[key] = source[key]; } return target; }
接下来我们实现一个
foo类 和
bar类,然后将两个类进行
mixin,生成一个新的类,具体代码如下所示:
const bar = { technical: function () { console.log("跳"); }, moment: function () { this.technical(); }, }; const foo = { nickname: "xun", hobby: "nba", age: 18, moment: function () { bar.moment.call(this); }, }; console.log(mixin(bar, foo));
现在返回的新对象中就有了一份
bar对象的属性和函数的副本了,从技术角度来说,函数实际上没有被复制,复制的是函数引用。
所以返回的新对象中的属性
thchnical方法只是从
bar中复制过来的对与
moment函数的引用,相反
moment()就是直接从
bar中复制了值 1。
foo已经有了
moment方法,所以这个属性引用并没有被
mixin重写,从而保留了
foo中定义的同名方法,实现了子类对子类属性的重写。
显示混入模式的一种变体被称为
寄生继承,它既是显示的又是隐式的,具体代码如下所示:
function Foo() { this.nickname = "moment"; } Foo.prototype.ignition = function () { console.log("小黑子"); }; Foo.prototype.小黑子 = function () { this.ignition(); console.log("叼毛"); }; // 寄生类 function Bar() { const foo = new Foo(); foo.age = 18; const 你小子 = foo.小黑子; foo.小黑子 = function () { 你小子.call(this); console.log("不是所有的牛奶都是特仑苏"); }; return foo; } const result = new Bar(); console.log(result);
该代码的最终输出结果如下所示:
就像你看到的一样,首先我们复制一份
Foo父类对象的定义,然后混入子类独享的定义。
隐式混入
隐式混入示例代码如下所示:
const something = { cool: function () { this.greeting = "hello"; this.count = this.count ? this.count + 1 : 1; }, }; console.log(something.cool()); // undefined console.log(something.greeting); // hello console.log(something.count); // 1 const another = { cool: function () { something.cool.call(this); }, }; console.log(another.cool()); // undefined console.log(another.greeting); // hello console.log(another.count); // 1
在上面代码中通过在构造函数调用或者方法调用中使用
something.cool.call(this),让我们实际上
借用了函数
something.cool()函数并在
another的上下文中调用了它(通过
this指向),最终的结果是
something.cool()函数中的赋值操作都会应用在
another对象上而不是
something对象上。
因此我们把
something的行为混入到了
another中。