1

我有以下编

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);

当我运行它时,我得到堆栈溢出?为什么?

4

3 回答 3

6

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

于 2009-08-09T11:54:54.313 回答
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 的网站以及这两篇关于Javascript 继承的文章。

于 2009-08-09T15:08:37.443 回答
1

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

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

我还建议您看一下我发现非常干净的这种原型继承技术。

于 2009-08-09T15:24:38.113 回答