mixin 是一个对象,可以使用它来向另一个对象或类添加可重用的功能,而无需使用继承。
不能单独使用 mixin:它们的唯一目的是在没有继承的情况下向对象或类添加功能。
创建一个 mixin
假设对于我们的应用程序,需要创建多个狗。 然而,创建的基本狗没有任何属性,只有一个名称属性。
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.assign
方法将 dogFunctionality mixin 添加到 Dog 原型中。
此方法向目标对象添加属性:在本例中为 Dog.prototype
。
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);
创建第一个宠物 pet1,称为 Daisy。
由于刚刚在 Dog 的原型中添加了 dogFunctionality mixin,Daisy 应该能够走路、睡觉和玩耍!
|
|
Perfect! Mixins 使我们可以轻松地向类或对象添加自定义功能,而无需使用继承。
从 mixin 继承
虽然可以在没有继承的情况下使用 mixin 添加功能,但 mixin 本身可以使用继承!
大多数哺乳动物(除了海豚……也许还有更多)也可以走路和睡觉。 狗是哺乳动物,应该会走路和睡觉!
让我们创建一个添加步行和睡眠属性的 animalFunctionality mixin。
可以使用 Object.assign 将这些属性添加到 dogFunctionality 原型中。 在这种情况下,目标对象是 dogFunctionality。
|
|
|
|
Perfect! Dog 的任何新实例现在也可以访问 walk 和 sleep 方法。
浏览器中的 mixin
现实世界中的 mixin 示例在浏览器环境中的 Window 界面上可见。
Window 对象从 WindowOrWorkerGlobalScope
和 WindowEventHandlers
混合中实现了它的许多属性,
这允许我们访问诸如 setTimeout 和 setInterval、indexedDB 和 isSecureContext 等属性。
由于它是一个 mixin,因此仅用于向对象添加功能,无法创建 WindowOrWorkerGlobalScope 类型的对象。
|
|
React (ES6之前)
在引入 ES6 类之前,通常使用 Mixin 向 React 组件添加功能。
React 团队不鼓励使用 mixin,因为它很容易给组件增加不必要的复杂性,使其难以维护和重用。
React 团队鼓励使用高阶组件,现在通常可以用 Hooks 代替。
缺点
Mixins 允许我们通过将功能注入对象的原型,轻松地向对象添加功能而无需继承。
修改一个对象的原型被视为不好的做法,因为它会导致原型污染和函数来源的一定程度的不确定性。
知识点
- Object.assign 用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。