2017-03-16 85 views
0

我想用JavaScript来模仿更类的继承模型,但是当我尝试将这与JavaScript代理的想法混合时遇到了问题。为了长话短说,在我的类类型的定义中,我有一个函数_super(),其语义为“当子类B的实例上的方法X调用_super()时,调用父类上的方法X A类“:代理用法弄错函数function.caller.name

Class A 
    .X() {...} 
^
    | 
    | 
Class B 
    .X() {..._super(); ...} 

我依靠功能 .caller.name办法让我调用方法的名称(在本例中,‘X’)。然后我在父类上调用它。

const Class = { 
... 
    _super: function _super(...args) { 
     // Get a handle on the function in which this function is invoked: 
     const callerMethod = _super.caller.name; 
     ... 
    }, 
... 
}; 

这个工作正常。当我在我的Class结构上添加一个Proxy对象时(我想捕获一些方法调用),问题就开始了。现在

function traceMethodCalls(obj) { 
    const handler = { 
    get(target, propKey, receiver) { 
     const origMethod = target[propKey]; 
     return function (...args) { 
     // Do stuff 
     }; 
    }, 
    }; 
    return new Proxy(obj, handler); 
} 

功能 .caller在_super()方法是在代理处理程序对象(显然...)的匿名函数,这打乱了程序流程。

我的问题:有没有办法绕过这个?或以不同的方式思考?或者我必须完全放弃* .caller.name方法?

回答

0

唯一想到的是检查堆栈以找到不是“_super”的第一个东西。相当愚蠢的海事组织,但它在这里。

const Class = { 
 

 
    _super: function _super(...args) { 
 
     let callerMethod; 
 

 
     let s = (new Error) 
 
      .stack.split('\n') 
 
      .slice(2); 
 
     while (s.length && s[0].includes('_super')) 
 
      s.shift(); 
 

 
     let m = (s[0] || '').match(/^\s*at\s\w+\.(\w+)/); 
 
     callerMethod = m ? m[1] : null; 
 
     console.log('super call [%s]', callerMethod) 
 
    }, 
 

 
    foo: function() { 
 
     this._super() 
 
    } 
 
}; 
 

 

 
function traceMethodCalls(obj) { 
 
    const handler = { 
 
     get(target, propKey, receiver) { 
 
      const origMethod = target[propKey]; 
 
      let f = { 
 
       [propKey]: function (...args) { 
 
        console.log('tracing', propKey) 
 
        origMethod.bind(this)() 
 
       } 
 
      }; 
 
      return f[propKey]; 
 
     }, 
 
    }; 
 
    return new Proxy(obj, handler); 
 
} 
 

 
obj = Object.create(Class) 
 
obj.foo() 
 
traced = traceMethodCalls(obj) 
 
traced.foo()

一般情况下,依靠功能名称中总是危险(想想uglifiers等)。我想可以公平地说,你不能在没有某种预编译的情况下在js中工作,而不能使用super。注释。

+0

谢谢!是的,好像我可能不得不重新考虑我的方法。 – Cristina