如何将mixins添加到ES6 javascript类?

use*_*159 19 javascript class node.js ecmascript-6 lodash

在具有一些实例变量和方法的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)
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我运行(new Test()).test(),它将失败,因为method2类中没有,因为它在mixin中,这就是为什么我需要将mixin变量和方法添加到类中.

我看到有一个lodash mixin函数https://lodash.com/docs/4.17.4#mixin,但我不知道如何在ES6类中使用它.我很好地使用lodash作为解决方案,甚至是没有库的普通JS来提供mixin功能.

lon*_*day 23

Javascript的对象/属性系统比大多数语言更加动态,因此向对象添加功能非常容易.由于函数是第一类对象,因此可以以完全相同的方式将它们添加到对象中.Object.assign是将一个对象的属性添加到另一个对象的方法.(它的行为在许多方面与之相当_.mixin.)

Javascript中的类只是语法糖,使得添加构造函数/原型对变得简单明了.该功能并未从ES6之前的代码更改.

您可以将属性添加到原型:

Object.assign(Test.prototype, mixin);
Run Code Online (Sandbox Code Playgroud)

您可以在构造函数中将它添加到每个创建的对象:

constructor() {
    this.var1 = 'var1';
    Object.assign(this, mixin);
}
Run Code Online (Sandbox Code Playgroud)

您可以根据条件在构造函数中添加它:

constructor() {
    this.var1 = 'var1';
    if (someCondition) {
        Object.assign(this, mixin);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者您可以在创建对象后将其分配给对象:

let test = new Test();
Object.assign(test, mixin);
Run Code Online (Sandbox Code Playgroud)

  • @lonesomeday 出于兴趣,如果 mixin 是在与 Object 不同的文件中声明的,那会是什么样子。如在 mixin 文件上的导出和目标文件上的要求(或声明对象的地方) (2认同)
  • 如果这展示了如何进行混合,其中您要混合的东西是 ES6 类本身(例如目标和源都是 ES6 类),那就太好了。在我看来,`Object.assign()` 不起作用,可能是因为 ES6 方法默认情况下不是可迭代的。 (2认同)

Jam*_*ate 16

在 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');
  }
};
Run Code Online (Sandbox Code Playgroud)
class MyClass extends MyMixin(MyBaseClass) {
  /* ... */
}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,该文章提供了虚假信息。他指出 MixIn 为“instanceOf()”提供了肯定;这是不正确的。同样的误解也是他整个技巧的基础。他正在拉长继承链。MixIns从水平方向加入一个Class,但他是在垂直方向延伸继承链。 (6认同)
  • 继承和混合是两种不同的操作。在大多数语言中(那些不知道如何解决[钻石问题](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem)的语言),您只能从一个超类继承。但在每种语言中,您都可以根据需要混合任意数量的课程。 (4认同)