前端设计模式学习系列文章-混合模式

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

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

js 复制代码
class Dog {
  constructor(name) {
    this.name = name;
  }
}

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

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

我们可以使用该方法将dogFunctionalitymixin 添加到原型中。此方法允许我们向目标对象 添加属性:在本例中。每个新实例都可以访问 的属性,因为它们被添加到 的原型中!Dog``Object.assign**Dog.prototype``Dog``dogFunctionality``Dog

js 复制代码
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叫做黛西。由于我们刚刚将dogFunctionalitymixin 添加到 的原型中Dog,Daisy 应该能够走路、摇尾巴和玩耍!

js 复制代码
const pet1 = new Dog("Daisy");

pet1.name; // Daisy
pet1.bark(); // Woof!
pet1.play(); // Playing!

完美的!Mixins 使我们可以轻松地向类或对象添加自定义功能,而无需使用继承。


虽然我们可以使用 mixins 添加功能而无需继承,但 mixins 本身可以使用继承!

大多数哺乳动物(除了海豚......也许还有更多)也可以行走和睡眠。狗是哺乳动物,应该能够行走和睡觉!

让我们创建一个animalFunctionality添加walksleep属性的 mixin。

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

我们可以dogFunctionality使用 将这些属性添加到原型中Object.assign。在这种情况下,目标对象是dogFunctionality

js 复制代码
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);

完美的!的任何新实例Dog现在也可以访问walksleep方法。

js 复制代码
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("Daisy");

console.log(pet1.name);
pet1.bark();
pet1.play();
pet1.walk();
pet1.sleep();

Window现实世界中 mixin 的示例在浏览器环境中的界面上可见。该对象通过和mixinWindow实现了它的许多属性,这使我们能够访问诸如and 、和 之类的属性。WindowOrWorkerGlobalScopeWindowEventHandlerssetTimeout``setInterval``indexedDB``isSecureContext

由于它是一个 mixin,因此仅用于向对象添加功能 ,因此您将无法创建 类型的对象WindowOrWorkerGlobalScope

js 复制代码
window.indexedDB.open("toDoList");

window.addEventListener("beforeunload", event => {
  event.preventDefault();
  event.returnValue = "";
});

window.onbeforeunload = function() {
  console.log("Unloading!");
};

console.log(
  "From WindowEventHandlers mixin: onbeforeunload",
  window.onbeforeunload
);

console.log(
  "From WindowOrWorkerGlobalScope mixin: isSecureContext",
  window.isSecureContext
);

console.log(
  "WindowEventHandlers itself is undefined",
  window.WindowEventHandlers
);

console.log(
  "WindowOrWorkerGlobalScope itself is undefined",
  window.WindowOrWorkerGlobalScope
);

React(ES6 之前)

在引入 ES6 类之前,Mixin 通常用于向 React 组件添加功能。React 团队不鼓励使用 mixins,因为它很容易给组件增加不必要的复杂性,使其难以维护和重用。React 团队鼓励使用更高阶的组件,这些组件现在通常可以被 Hook 取代。


Mixins 允许我们通过将功能注入到对象的原型中,轻松地向对象添加功能,而无需继承。修改对象的原型被认为是不好的做法,因为它可能导致原型污染以及函数起源的一定程度的不确定性。

相关推荐
触底反弹2 小时前
🤯 面试被问 AI Workflow 和 Agent 有啥区别?3 张图 + 2 段代码讲清楚!
人工智能·设计模式·面试
杨充1 天前
10.可测试性实战设计
设计模式·开源·代码规范
杨充1 天前
9.重构十二式的实战
设计模式·开源·代码规范
杨充1 天前
6.设计原则的全景图
设计模式·开源·全栈
杨充1 天前
2.面向对象的特性
设计模式
杨充1 天前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充1 天前
8.反模式与坏味道
设计模式·开源·代码规范
杨充1 天前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法