javascript继承中的堆栈溢出

时间:2009-08-09 11:46:42

标签: javascript stack-overflow

我有以下编程

Object.prototype.inherit = function(baseConstructor) {
  this.prototype = (baseConstructor.prototype);
  this.prototype.constructor = this;
};
Object.prototype.method = function(name, func) {
  this.prototype[name] = func;
};

function StrangeArray(){}
StrangeArray.inherit(Array);
StrangeArray.method("push", function(value) {
  Array.prototype.push.call(this, value);
});

var strange = new StrangeArray();
strange.push(4);
alert(strange);

当我看到堆栈溢出时?为什么呢?

3 个答案:

答案 0 :(得分:6)

您将StrangeArray.prototype设为Array.prototype。之后,您要向push添加StrangeArray.prototype方法(现在与Array.prototype相同)。所以你有效地设置了Array.prototype.push。您的push方法会调用Array.prototype.push - 即自己。所以它最终只是反复调用自己,并且你得到一个堆栈溢出。

答案 1 :(得分:2)

乔是对的。这是一种解决方法。不是将StrangeArray.prototype设置为Array.prototype,而是将StrangeArray.prototype设置为Array的新实例,因此它继承了Array.prototype的属性(不调用Array的构造函数)。

Object.prototype.inherit = function(baseConstructor) {
  var tmp = Function();
  tmp.prototype = baseConstructor.prototype;
  this.prototype = new tmp();
  this.prototype.constructor = this;
};

编辑:

this.prototype = new baseConstructor();

适用于此示例,但在更复杂的程序中效果不佳。如果基础构造函数进行了一些初始化,例如创建DOM元素,递增计数或连接到服务器,那么所有初始化都将在脚本加载时进行,而不是在实例化子对象时进行。

另一种解决这个问题的方法是在构造函数中区分它是被调用继承(分配给原型)还是仅仅实例化,然后在调用继承时不进行初始化。但我更喜欢在继承时不调用构造函数,因此在继承时使用空函数作为构造函数。

我不太擅长解释这些东西。我推荐Crockford的网站以及two articles上的这些Javascript inheritance

答案 2 :(得分:1)

实际上你只需要将实际对象的原型设置为baseConstructor的新实例:

Object.prototype.inherit = function(baseConstructor) {
  this.prototype = new baseConstructor();
};

我还建议你看一下我发现非常干净的Prototypal Inheritance技术。