Mixin

    但是,这大大降低了编程的灵活性。因为实际开发中,有时不可避免,子类需要继承多个父类。举例来说,“猫”可以继承“哺乳类动物”,也可以继承“宠物”。

    各种单一继承的编程语言,有不同的多重继承解决方案。比如,Java 语言也是子类只能继承一个父类,但是还允许继承多个界面(interface),这样就间接实现了多重继承。Interface 与父类一样,也是一个类,只不过它只定义接口(method signature),不定义实现,因此又被称为“抽象类”。凡是继承于 Interface 的方法,都必须自己定义实现,否则就会报错。这样就避免了多重继承的最大问题:多个父类的同名方法的碰撞(naming collision)。

    JavaScript 语言没有采用 Interface 的方案,而是通过代理(delegation)实现了从其他类引入方法。

    上面代码中,是一个数组,本身并没有first方法。通过call方法,可以把Enumerable_first里面的方法,绑定到list,从而list就具有first方法。这就叫做“代理”(delegation),list对象代理了Enumerable_firstfirst方法。

    它允许向一个类里面注入一些代码,使得一个类的功能能够“混入”另一个类。实质上是多重继承的一种解决方案,但是避免了多重继承的复杂性,而且有利于代码复用。

    Mixin 就是一个正常的类,不仅定义了接口,还定义了接口的实现。

    子类通过在对象上面绑定方法,达到多重继承的目的。

    很多库提供了 Mixin 功能。下面以 Lodash 为例。

    Underscore 的类似方法是_.extend

    上面代码通过_.extend方法,在sam对象上面(准确说是它的原型对象Person.prototype上面),混入了NameMixin类。

    extend方法的实现非常简单。

    上面代码将对象的所有方法,添加到destination对象。

    Trait