我正在尝试覆盖对象的方法,但仍使用Object.getPrototypeOf()
调用原型的原始方法。这在第一次工作得很好,但是如果方法被多次覆盖则存在问题。
此代码导致堆栈溢出:
A =
{
blurg: function()
{
puts('hey there')
}
}
B = (function buildB(){
var obj = Object.create(A)
obj.blurg = function()
{
Object.getPrototypeOf(this).blurg.apply(this, arguments)
puts('hai!!!!')
}
return obj
})()
b = (function buildb(){
var obj = Object.create(B)
obj.blurg = function()
{
Object.getPrototypeOf(this).blurg.apply(this, arguments)
puts('bye bye')
}
return obj
})()
b.blurg()
问题是我想用当前对象调用原型的方法this
。当该方法做同样的事情时,这会导致问题。
我是以错误的方式来做这件事的吗?有没有办法可以创建一个辅助函数来确保正确的原型被拉起来?我有点不知所措。
答案 0 :(得分:3)
问题在于,在JavaScript中,this
本质上总是引用原型链中的自底向下对象实例,因此当您覆盖上述层次结构中的方法时,this.prototype.someMethod()
指的是对象实例的确切基类,当您最多有两个层次结构时,它似乎不是问题,但是当您定义三个层次结构或更多层次时,递归是不可避免的!这是如何:
A: grand super class
B: super class - inherits from A (B.prototype = A)
C: class - inherits from B (C.prototype = B)
a: instance of A (defines someMethod)
b: instance of B (defines someMethod, calls A.someMethod through Object.getPrototypeOf(this))
c: instance of C (defines someMethod, calls B.someMethod through Object.getPrototypeOf(this))
调用b.someMethod
时,它可以成功调用A的someMethod(Object.getPrototypeOf(this)
在被b调用时返回A)
但是,当c.someMethod
被调用时,它首先调用b.someMethod
,然后调用b.someMethod
,因为Object.getPrototypeOf(this)
在被c调用时总是返回B!这里是堆栈溢出的地方。
要解决此问题,请在定义新的子类时尝试存储基类引用,避免在调用超类方法时使用this
:
A =
{
blurg: function () {
console.log('hey there')
}
};
B = (function buildB() {
var obj = Object.create(A);
var base = Object.getPrototypeOf(obj);
obj.blurg = function () {
base.blurg.apply(this, arguments);
console.log('hai!!!!')
}
return obj
})();
C = (function buildb() {
var obj = Object.create(B);
var base = Object.getPrototypeOf(obj);
obj.blurg = function () {
base.blurg.apply(this, arguments);
console.log('bye bye');
}
return obj
})();
C.blurg();