Call prototype's overridden method which then calls the next prototype's overridden method error

随声附和 提交于 2019-12-11 09:51:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!