Mixin是一个对象,我们可以使用它来为另一个对象或类添加可重用的功能,而无需使用继承。我们不能单独使用mixins:它们的唯一目的是在没有继承的情况下向对象或类添加功能。

假设对于我们的应用程序,我们需要创建多个狗。然而,我们创建的基本狗没有任何属性,只有一个name属性。

class Dog {constructor(name) {this.name = name;}}

一只狗能做的不仅仅是有一个名字。它应该会叫,会摇尾巴,会玩!我们可以创建一个mixin,为我们提供bark, wagTail和play属性,而不是直接添加到Dog类中。

const dogFunctionality = {bark: () => console.log("Woof!"),wagTail: () => console.log("Wagging my tail!"),play: () => console.log("Playing!"),};

我们可以用Object.assigndogFunctionality添加到Dog原型中。这样Dog的每个新实例都可以访问dogFunctionality的属性,因为它们被添加到Dog的原型中!

class Dog {constructor(name) {this.name = name;}}const dogFunctionality = {bark: () => console.log("Woof!"),wagTail: () => console.log("Wagging my tail!"),play: () => console.log("Playing!"),};Object.assign(Dog.prototype, dogFunctionality);

现在可以创建我们的第一个宠物叫卡迪。正如我们刚刚将dogFunctionality mixin添加到Dog的原型中一样,卡迪应该能够走路、摇尾巴和玩耍!

const pet1 = new Dog("Kadi");pet1.name; // Kadipet1.bark(); // Woof!pet1.play(); // Playing!

虽然我们可以在没有继承的情况下使用mixin添加功能,但是mixin本身可以使用继承。
大多数哺乳动物(除了海豚…也许更多)也能走路和睡觉。狗是哺乳动物,应该能够走路和睡觉。

接下来创建一个animalFunctionality mixin,它有 walksleep 属性。

const animalFunctionality = {walk: () => console.log("Walking!"),sleep: () => console.log("Sleeping!"),};

walksleep属性通过 Object.assign方法添加到dogFunctionality原型中。在这个例子中, dogFunctionality是目标对象。

const animalFunctionality = {walk: () => console.log("Walking!"),sleep: () => console.log("Sleeping!"),};const dogFunctionality = {bark: () => console.log("Woof!"),wagTail: () => console.log("Wagging my tail!"),play: () => console.log("Playing!"),walk() {super.walk();},sleep() {super.sleep();},};Object.assign(dogFunctionality, animalFunctionality);Object.assign(Dog.prototype, dogFunctionality);

完整示例代码

class Dog {constructor(name) {this.name = name;}}const animalFunctionality = {walk: () => console.log("Walking..."),sleep: () => console.log("Sleeping..."),};const dogFunctionality = {__proto__: animalFunctionality,bark: () => console.log("Woof!"),wagTail: () => console.log("Wagging my tail!"),play: () => console.log("Playing!"),walk() {super.walk();},sleep() {super.sleep();}};Object.assign(Dog.prototype, dogFunctionality);const pet1 = new Dog("Kadi");console.log(pet1.name);pet1.bark();pet1.wagTail();pet1.walk();

小知识

Object.assign()

静态方法将一个或者多个源对象中所有可枚举自有属性复制到目标对象,并返回修改后的目标对象。

[语法]
Object.assign(target, ...sources)
[参数]
  • [target]

    需要应用源对象属性的目标对象,修改后将作为返回值。

  • [sources]

    一个或多个包含要应用的属性的源对象。

[返回值]

修改后的目标对象。