JavaScript中的原型继承

时间:2008-12-23 16:45:04

标签: javascript inheritance prototypal-inheritance

我一直在观看Douglas Crockford在YUI剧院的演讲,我对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 个答案:

答案 0 :(得分:17)

原因是使用Hoozit.prototype = Gizmo.prototype意味着修改Hoozit的原型对象也会修改Gizmo类型的对象,这不是预期的行为。

Hoozit.prototype = new Gizmo()继承自Gizmo,然后单独离开Gizmo。

答案 1 :(得分: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 Examples 中有很多这类模式的例子。

答案 2 :(得分:2)

如果他写Hoozit.prototype = Gizmo.prototype,他后来对Hoozit原型的任何修改都会反映在Gizmo的原型中。

答案 3 :(得分:2)

除了Triptych的回答:Hoozit实例还将继承Gizmo的所有实例属性,而不仅仅是原型中定义的属性;例如:

function Gizmo() {
    this.foo = 'bar'; // foo is visible in every Hoozit instance
}