如何向 ES6 javascript 类添加 mixins?
Posted
技术标签:
【中文标题】如何向 ES6 javascript 类添加 mixins?【英文标题】:How to add mixins to ES6 javascript classes? 【发布时间】:2017-07-03 23:58:41 【问题描述】:在带有一些实例变量和方法的 ES6 类中,如何向其中添加 mixin?我在下面给出了一个例子,虽然我不知道 mixin 对象的语法是否正确。
class Test
constructor()
this.var1 = 'var1'
method1()
console.log(this.var1)
test()
this.method2()
var mixin =
var2: 'var2',
method2:
console.log(this.var2)
如果我运行(new Test()).test()
,它将失败,因为类上没有method2
,因为它在mixin中,这就是为什么我需要将mixin变量和方法添加到类中。
我看到有一个 lodash mixin 函数https://lodash.com/docs/4.17.4#mixin,但我不知道如何将它与 ES6 类一起使用。我可以使用 lodash 作为解决方案,甚至可以使用没有库的普通 JS 来提供 mixin 功能。
【问题讨论】:
【参考方案1】:javascript 的对象/属性系统比大多数语言动态得多,因此向对象添加功能非常容易。由于函数是一等对象,它们可以以完全相同的方式添加到对象中。 Object.assign
是将一个对象的属性添加到另一个对象的方法。 (它的行为在很多方面都可以与_.mixin
媲美。)
Javascript 中的类只是使添加构造函数/原型对变得简单明了的语法糖。该功能与 ES6 之前的代码相比没有变化。
您可以将属性添加到原型中:
Object.assign(Test.prototype, mixin);
您可以在构造函数中将它添加到创建的每个对象:
constructor()
this.var1 = 'var1';
Object.assign(this, mixin);
您可以根据条件将其添加到构造函数中:
constructor()
this.var1 = 'var1';
if (someCondition)
Object.assign(this, mixin);
或者您可以在创建对象后将其分配给对象:
let test = new Test();
Object.assign(test, mixin);
【讨论】:
@lonesomeday 将它添加到对象本身的原型有什么区别?我认为在声明方法时最好在原型上进行,因为这样所有对象都共享相同的功能,而不是它们都有自己的功能来做同样的事情。这是否也适用于这种混合技术,将其应用于原型比对象更有效? @user779159 该函数只会存在一次。只有当您再次声明该函数时,才会创建第二个函数。 (例如,如果你有一个装饰器函数,它每次运行时都会创建一个新函数。) @lonesomeday 出于兴趣,如果 mixin 是在与 Object 不同的文件中声明的,那会是什么样子。就像 mixin 文件上的导出和目标文件(或声明对象的位置)上的要求一样 如果这显示了如何做一个混合,你正在混合的东西是一个 ES6 类本身(例如,目标和源都是 ES6 类)。在我看来,Object.assign()
对此不起作用,可能是因为 ES6 方法默认情况下不可迭代。【参考方案2】:
在 es6 中,您可以在不分配的情况下执行此操作,甚至可以在正确的时间调用 mixin 构造函数!
http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/#bettermixinsthroughclassexpressions
此模式使用class expressions
为每个mixin 创建一个新的基类。
let MyMixin = (superclass) => class extends superclass
foo()
console.log('foo from MyMixin');
;
class MyClass extends MyMixin(MyBaseClass)
/* ... */
【讨论】:
很遗憾,该文章提供了虚假信息。他说 MixIn 提供了对“instanceOf()”的肯定;这是不正确的。同样的误解是他整个技术的基础。他正在加长继承链。 MixIns从水平方向加入一个Class,但他是在垂直延伸继承链。 我认为扩展继承链是更好的方法。 instanceof 只是一个附带好处,并且需要一些花哨的步法。 Otoh 使用这种方法,您可以以受控方式运行构造函数逻辑,这是主要好处。 继承和混入是两种不同的操作。在大多数语言中(那些不知道如何解决diamond problem 的人),您只能从一个超类继承。但是在每种语言中,您都可以根据需要混合任意数量的课程。 任何一种方式都是定义语言特性的完美有效方式,允许您向许多类添加通用功能,并且文章非常清楚地提供了哪些语义,因此没有混淆的危险.此外,语义与 ruby 中称为 mixins 的模块包含并没有真正的不同(在这里,当您包含一个模块时,您会覆盖其他模块中通常调用的方法)。【参考方案3】:你应该看看Object.assign()
。看起来应该是这样的:
Object.assign(Test.prototype, mixin);
这将确保来自mixin
的所有方法和属性都将被复制到Test
构造函数的原型对象中。
【讨论】:
有没有办法从class
本身调用它?
这是非常值得怀疑的。这是因为 ES6 类只是隐藏了良好的原型继承的语法糖。所以它们基本上都是经过修饰的构造函数。
相关***.com/questions/46795498/…以上是关于如何向 ES6 javascript 类添加 mixins?的主要内容,如果未能解决你的问题,请参考以下文章
javascript:仅当父元素处于活动状态且子元素具有特定类时,如何向子元素添加属性?