我的问题必须是错误的,因为我无法找到关于经常出现问题的现有问题。
我有一个班级Foo
。
var Foo = function () {
return {
a: function () {}
};
};
我有另一个用Bar
实例实例化的类Foo
:
var Bar = function (foo) {
// Does something with foo.
};
我希望将Foo
实例扩展为Bar
的工作方式:
var Bar = function (foo) {
foo.a = function () {
return foo.a.apply(this, arguments);
};
// Does something with foo.
};
按照我的方式行事,将导致RangeError: Maximum call stack size exceeded
。有没有办法在没有临时变量的情况下扩展方法本身?
这是使用额外变量的方法:
var Bar = function (foo) {
var originala;
originala = foo.a;
foo.a = function () {
return originala.apply(this, arguments);
};
// Does something with foo.
};
答案 0 :(得分:1)
问题:
您正在获得超出最大调用堆栈,因为您正在反复调用相同的函数(递归)。
原因:
构建Foo
时,会获得一个分配给其属性a
的函数。一切都很好。
接下来,构造Bar
并尝试通过用您自己的对象替换对象上的函数来修改Foo.a
的行为。但是,您希望在新函数体内,Foo.a
仍将包含原始函数。反之亦然 - Foo.a
现在包含您的新修改函数。这就是为什么当你调用它时,它会一直调用自己,直到你点击maximum stack size limit。
这是因为变量的值在执行时被解析,并且新函数在被分配给Foo.a
后执行得很好。此对象的原始功能将丢失。
解决方案:
使用prototypes。我不会详细介绍如何使用原型继承,因为周围有很多浮动。
请注意,您的方法是有效的,通常是唯一的方法。您只需要在某处保留对原始函数的引用,以便以后可以调用它。
答案 1 :(得分:0)
这在使用 classes 时变得非常容易。
class Foo {
a(){
return /* Something */
}
}
class Bar extends Foo {
a(){
/* Do something else */
return super.a()
}
}
6 年前提出这个问题时,大多数浏览器(如果有)都无法做到这一点,但是 every modern browser now supports classes。