繁体   English   中英

如何将 mixin 添加到 ES6 javascript 类?

[英]How to add mixins to ES6 javascript classes?

在带有一些实例变量和方法的 ES6 class 中,如何向其中添加混合? 我在下面给出了一个示例,但我不知道 mixin object 的语法是否正确。

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() ,它将失败,因为 class 上没有method2 ,因为它在 mixin 中,这就是为什么我需要将 mixin 变量和方法添加到 class。

我看到有一个 lodash mixin function https://lodash.com/docs/4.17.4#mixin ,但我不知道如何将它用于 ES6 类。 我可以使用 lodash 作为解决方案,甚至可以使用没有库的纯 JS 来提供混合功能。

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);

在 es6 中,你可以在不赋值的情况下做到这一点,你甚至可以在正确的时间调用 mixin 构造函数!

http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/#bettermixinsthroughclassexpressions

此模式使用class expressions为每个混合创建一个新的基础 class。

let MyMixin = (superclass) => class extends superclass {
  foo() {
    console.log('foo from MyMixin');
  }
};
class MyClass extends MyMixin(MyBaseClass) {
  /* ... */
}

你应该看看Object.assign() 看起来像这样:

Object.assign(Test.prototype, mixin);

这将确保mixin所有方法和属性都将被复制到Test构造函数的原型对象中。

我很惊讶地发现,没有一个答案提到我认为在组合意义上的混合(与继承相反),对我来说,它是一个 function,它为 object 添加了功能。这是一个使用的示例inheritance 和组成:

 class Pet { constructor(name) { this.name = name } } class Cat extends Pet { expression = 'miaow' } class Dog extends Pet { expression = 'bark' } class Human { constructor(name, age) { this.name = name; this.age = age; } } class American extends Human { expression = 'say howdy' } function canSayHello(...contexts) { for (const context of contexts) { context.sayHello = function() { console.log(`Hello my name is ${this.name} and I ${this.expression}`) } } } canSayHello(Pet.prototype, Human.prototype); // apply the mixin const garfield = new Cat('garfield'); const pluto = new Dog('pluto'); const joebiden = new American('Joe Biden', 79); garfield.sayHello(); pluto.sayHello(); joebiden.sayHello();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM