问题
I'm trying to override methods of an object but still call the prototype's original method using Object.getPrototypeOf()
. This works great the first time, but if the method is overridden more than once there are problems.
This code results in a stack overflow:
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()
jsFiddle
The problem is that I want to call the prototype's method with the current object as this
. This causes problems when that method does the same thing.
Am I going about this the wrong way? Is there a way I could create a helper function for making sure the correct prototype is pulled up? I'm a bit at a loss.
回答1:
The problem is that in JavaScript, by nature, this
always refers to the bottom down object instance in a prototype chain, so when you override methods in a hierarchical structure like above, this.prototype.someMethod()
refers to the exact base class of the object instance, it doesn't seem to be a problem when you have maximum of two levels of hierarchy, however when you define three levels of hierarchical structure or more, recursion is inevitable! here's how:
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))
When b.someMethod
is called, it can successfully call A's someMethod (Object.getPrototypeOf(this)
returns A when called by b)
However when c.someMethod
is called, it first calls b.someMethod
, which in turn calls b.someMethod
because Object.getPrototypeOf(this)
always returns B when called by c! And here's where stack overflow occurs.
To resolve this, try to store a base class reference whenever you define a new sub-class, avoid using this
when calling a super-class method:
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();
来源:https://stackoverflow.com/questions/10588907/call-prototypes-overridden-method-which-then-calls-the-next-prototypes-overrid