Как добавить миксины в классы JavaScript javascript?

В классе 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/property system намного более динамичен, чем большинство языков, поэтому очень легко добавить функциональность к объекту. Поскольку функции являются первоклассными объектами, они могут быть добавлены к объекту точно так же. Object.assign - это способ добавления свойств одного объекта к другому объекту. (Его поведение во многом сопоставимо с _.mixin.)

Классы в Javascript - это только синтаксический сахар, который упрощает и упрощает добавление пары конструктор/прототип. Функциональность не изменилась с кода pre-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);

Ответ 2

Вероятно, вам стоит взглянуть на Object.assign(). Должен выглядеть примерно так:

Object.assign(Test.prototype, mixin);

Это гарантирует, что все методы и свойства из mixin будут скопированы в объект-прототип конструктора Test.

Ответ 3

В es6 вы можете делать это без присваивания и даже вызывать конструктор mixin в нужное время!

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

Этот шаблон использует class expressions для создания нового базового класса для каждого миксина.

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