JavaScript 已经成为众人关注的开发语言,JavaScript已经有了相当大的进步--一个真实意义上的自助开发。但是有一种基于 Mixin 的增强模式在日常开发中很少被使用的。Mixins 经常被一些 JavaScript 所忽略掉(我也经常这么干)。我不想抱怨但是 Mixins 有时候会让代码变得难以读懂。但 Mixins 也有许多优点可以供我们使用的。

Mixin 模式--如名字一样--是一种把一个对象与其他对象混合在一起来增加我们所需要的属性。把它想成一个可以让你的对象新增额外属性但是这些独立的属性却不是真正意义上成为子类挂靠在对象上。

在表面看来,mixins 就像是把目标(mixin)插入到源对象的混合层。目标会被插入到源对象中并且产生一个新的对象返回。

一个更加准确的描述是--一个 mixin 就像一个新建子类对象并返回的工厂。通过整个过程,不会再有关于子类的任何定义。

用更加 C++ 的类比来对比就是在抽象类上的虚拟函数,允许它们去被别的子类进行继承。

所以,现在我们都清楚 mixins 允许我们创建一个可改变的声明,通过这个声明,可以通过存在的父类创建一个新的子类。下面让我们来看下具体实践中 mixin 是怎么工作的:

//The swim property here is the mixin
let swim = {
  location() {
    console.log(`Heading ${this.direction} at ${this.speed}`);
  }
};

let Alligator = function(speed, direction) {
  this.speed = speed,
  this.direction = direction
};

//This is our source object
let alligator = new Alligator('20 mph','North');

alligator = Object.assign(alligator, swim);
console.log(alligator.location());

在上面的演示中,我想创建一个可以调用 swim 方法的 alligator 实例。所以我先 new 了一个 alligator 实例并且把 swim 对象合上去。swim 对象就是 mixin 或者换种说法是我们想给 alligator 对象通过 Object.assign 方法添加上去的扩展。

Object.assign 方法允许我们每次添加不止一个的 mixin。一个多 mixin 的例子如下所示:

alligator = Object.assign(alligator, swim, crawl);

现在我们来看下在 ES6 classes 中是怎么使用 mixins

let swim = {
 setSwimProperties(speed, direction) {
   this.speed = speed;
   this.direction = direction;
 },

 getSwimProperties(){
   console.log(`swimming ${this.speed} towards ${this.direction}`);
 }
}

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

Object.assign(Reptile.prototype, swim);
let alligator = new Reptile("alligator");
alligator.setSwimProperties("5 m/s", "upstream");
alligator.getSwimProperties();

通过 mixin 方法添加功能的优势在于灵活性。mixin 是一个非常原始的方法,因为它只负责一样事情,允许我们在各种情境下重复使用这些结构。它可以用在一个原生的函数调用、一个类的声明等等。

另外一个好处在于它试图让类的结构水平化--通过允许父类去利用这些 mixin 去创建一个指定子类属性的新的对象而不用更长的遗传链去创建子类。

在我们使用 mixins 的时候要牢记下面所提到的东西:

  • Object.assign(无论在 object 还是 class 实现中)只是对于这些 mixin 的属性进行浅拷贝。
  • 在使用从不同 mixin 中的属性时会存在潜在的命名冲突的问题(多重继承中的命名空间问题)
  • 在这些 mixin 属性被拷贝到源对象之后,我们基本没有办法去区分出这些属性究竟是从哪里来的。instanceof 操作符在这里并没有用武之地。

文章来源于腾讯云开发者社区,点击查看原文