当涉及到高级类组成时,JavaScript有相当多的方法 - 一个真正的选项。在野外很少见的一种模式是基于mixin的继承模式。Mixins通常被新的JavaScript程序员跳过(我也做了)。
混合模式 - 正如它的名字所暗示的那样 - 是将一个对象与其他对象混合在一起以添加我们需要的属性。
在表面上,混合物行为就像对象混合层,在那里我们传入目标(混合物)和源。
一个更准确的描述是,一个混合物作为一个工厂,返回新的子类对象,通过整个过程,没有任何地方对子类的定义。
更 C++ 的类似性是将它们与虚拟函数的抽象类进行比较,从而允许它们被其他子类继承。
因此,现在我们知道混合物允许我们创建一个修改的定义,可以应用到现有的超级类来创建新的子类,让我们看看混合物会是什么样子:
1//The swim property here is the mixin
2let swim = {
3 location() {
4 console.log(`Heading ${this.direction} at ${this.speed}`);
5 }
6};
7
8let Alligator = function(speed, direction) {
9 this.speed = speed,
10 this.direction = direction
11};
12
13//This is our source object
14let alligator = new Alligator('20 mph','North');
15
16alligator = Object.assign(alligator, swim);
17console.log(alligator.location());
在上面的片段中,我们想创建一个能游泳的鱼,所以我们创建一个新的鱼
,然后给它游泳
功能。
Object.assign
方法允许我们一次添加多个混合物。
1alligator = Object.assign(alligator, swim, crawl);
现在让我们看看如何使用混合物与 ES6 类:
1let swim = {
2 setSwimProperties(speed, direction) {
3 this.speed = speed;
4 this.direction = direction;
5 },
6
7 getSwimProperties(){
8 console.log(`swimming ${this.speed} towards ${this.direction}`);
9 }
10}
11
12class Reptile {
13 constructor(name) {
14 this.name = name;
15 }
16}
17
18Object.assign(Reptile.prototype, swim);
19let alligator = new Reptile("alligator");
20alligator.setSwimProperties("5 m/s", "upstream");
21alligator.getSwimProperties();
通过混合方法添加功能的优点是灵活性.混合是一种非常原始的功能,因为在它中只做一件事,使我们能够反复使用这些结构,并在各种场景中使用。
另一件好事是,它倾向于保持类等级水平 - 通过允许超级类使用混合物创建所需子类属性的新对象,而不是使继承链更长来为这些情况创建新的子类。
虽然使用混合物时需要记住的一些事情:
Object.assign
(在对象和类实现中都是)只对混合属性的微小副本 *在使用来自不同混合物的属性时可能会出现潜在的名称冲突(多重继承中的钻石问题) *很难弄清楚属性来自哪个混合物,因为属性被复制到源对象上。