web-dev-qa-db-fra.com

Comment ajouter des mixins aux classes javascript ES6?

Dans une classe ES6 avec quelques variables et méthodes d'instance, comment pouvez-vous y ajouter un mixin? J'ai donné un exemple ci-dessous, mais je ne sais pas si la syntaxe de l'objet mixin est correcte.

class Test {
  constructor() {
    this.var1 = 'var1'
  }
  method1() {
    console.log(this.var1)
  }
  test() {
    this.method2()
  }
}

var mixin = {
  var2: 'var2',
  method2: {
    console.log(this.var2)
  }
}

Si je lance (new Test()).test(), il échouera car il n'y a pas de method2 sur la classe, comme c'est dans le mixin, c'est pourquoi j'ai besoin d'ajouter les variables et méthodes mixin à la classe.

Je vois qu'il y a une fonction de mixage lodash https://lodash.com/docs/4.17.4#mixin , mais je ne sais pas comment je pourrais l'utiliser avec les classes ES6. Je suis d'accord avec l'utilisation de lodash pour la solution, ou même de JS simple sans bibliothèque pour fournir la fonctionnalité de mixage.

19
user779159

Le système d'objet/propriété de Javascript est beaucoup plus dynamique que la plupart des langues, il est donc très facile d'ajouter des fonctionnalités à un objet. Les fonctions étant des objets de première classe, elles peuvent être ajoutées à un objet exactement de la même manière. Object.assign est le moyen d'ajouter les propriétés d'un objet à un autre objet. (Son comportement est à bien des égards comparable à _.mixin.)

Les classes en Javascript ne sont que du sucre syntaxique qui rend l'ajout d'une paire constructeur/prototype facile et clair. La fonctionnalité n'a pas changé par rapport au code pré-ES6.

Vous pouvez ajouter la propriété au prototype:

Object.assign(Test.prototype, mixin);

Vous pouvez l'ajouter dans le constructeur à chaque objet créé:

constructor() {
    this.var1 = 'var1';
    Object.assign(this, mixin);
}

Vous pouvez l'ajouter dans le constructeur en fonction d'une condition:

constructor() {
    this.var1 = 'var1';
    if (someCondition) {
        Object.assign(this, mixin);
    }
}

Ou vous pouvez l'affecter à un objet après sa création:

let test = new Test();
Object.assign(test, mixin);
23
lonesomeday

Vous devriez probablement regarder Object.assign(). Je dois ressembler à quelque chose comme ça:

Object.assign(Test.prototype, mixin);

Cela garantira que toutes les méthodes et propriétés de mixin seront copiées dans l'objet prototype du constructeur Test.

3
Mister Spock

Dans es6, vous pouvez le faire sans assignation et vous pouvez même invoquer le constructeur mixin au bon moment!

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

Ce modèle utilise class expressions pour créer une nouvelle classe de base pour chaque mixage.

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