JavaScript中的原型继承

8

我一直在观看Douglas Crockford在YUI Theater的演讲,我有一个关于JavaScript继承的问题...

Douglas给出了这个例子来展示"Hoozit"从"Gizmo"继承:

function Hoozit(id) {
    this.id = id;
}
Hoozit.prototype = new Gizmo();
Hoozit.prototype.test = function (id) {
    return this.id === id;
};

为什么他要写 Hoozit.prototype = new Gizmo() 而不是 Hoozit.prototype = Gizmo.prototype

这两者之间有什么区别吗?

4个回答

17

原因是使用 Hoozit.prototype = Gizmo.prototype 会导致修改 Hoozit 的原型对象也会修改 Gizmo 类型的对象,这不是期望的行为。

Hoozit.prototype = new Gizmo() 继承自 Gizmo,然后独立于 Gizmo。


但是如果你想避免调用构造函数,你可以使用一些间接方式(寄生继承)。 - Rob

3
其他答案已经解决了这个问题,但如果你确实想要继承原型,可以使用一些寄生魔法:
Object.prototype.inherit = function(p) {
    NewObj = function(){};
    NewObj.prototype = p;
    return new NewObj(); 
};

// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
    var prototype = Object.inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
};

现在您可以替换以下内容:
Hoozit.prototype = new Gizmo();

使用

inheritPrototype(Hoozit, Gizmo);

除非您有一个真正大的Gizmo构造器(我的建议中唯一的胜利在于您不必调用Gizmo的构造器来连接原型),否则这可能不值得麻烦。我在TDD JavaScript示例中有许多这些类型模式的示例。


2
如果他写了Hoozit.prototype = Gizmo.prototype,那么他稍后对Hoozit原型的任何修改都将反映在Gizmo原型中。

2
除了Triptych的回答之外:Hoozit实例还将继承Gizmo的所有实例属性,而不仅仅是在原型中定义的属性。例如:
function Gizmo() {
    this.foo = 'bar'; // foo is visible in every Hoozit instance
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接