Javascript:如何将一个函数的原型附加到另一个?

Ada*_*dam 2 javascript merge prototype append

如何将一个函数的原型附加到另一个函数?就像是:

// Foo
function foo(){};
foo.prototype.a = 'hello';

// Bar
function bar(){}
bar.prototype.b = 'world';

// Append Foo's prototype to Bar
bar.appendPrototype(foo);

// Print
console.log(bar.prototype) // -> { a: 'hello', b: 'world' }
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 5

您可以迭代源原型的道具并将每个道具添加到目标原型。这假设 src 原型的属性是可以复制的简单属性(如函数或简单值,而不是对象本身),这通常是这种情况。如果要允许原型属性本身是嵌套对象,则需要克隆每个属性。通常这不是必需的,所以这里是更简单的版本:

bar.appendPrototype = function(src) {
    for (var prop in src.prototype) {
        this.prototype[prop] = src.prototype[prop];
    }
}

bar.appendPrototype(foo);
Run Code Online (Sandbox Code Playgroud)

原型只是对象,因此您可以将一个原型的属性复制到另一个原型。


几年后更新。 这种将方法从一个原型复制到另一个原型的一般概念创建了通常称为“混合”的东西,您可以将一个类的方法混合到另一个类中,以便创建一个具有两个对象功能的新对象。这是一篇关于该主题的有趣文章,有助于解释。

在实现 mixin 时,现在可以使用Object.assign()在一个函数调用中将属性从一个对象复制到另一个对象,而不是编写自己的循环。

您甚至可以对先前使用 ES6class语法声明的类进行混合。

mixin 的一个相当常见的例子是你已经有一个类层次结构(所以你不能只是继承),现在你想要一个叶类也是一个eventEmitter并且拥有该发射器的所有功能。您可以“混合” EventEmitter 对象,现在您之前声明的类也具有EventEmitter. 您需要采取的一项预防措施(与子类化时相同)是您需要确保两个对象实现之间没有任何实例属性名称冲突,因为 mixin 代码和您的代码都将访问相同的核心实例对象。

上面示例中混合的替代方法是将单独的 EventEmitter 对象添加到您的叶类实例数据中。如this.emitter = newEventEmitter() . Then, to access the emitter, rather thanthis.emit(...) , you would dothis.emitter.emit(...)`。这也有效,但通常不方便或简洁。