2017-03-16 77 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