2010-08-04 50 views
21

在此代碼中,我創建了一個名爲someFunction的函數。然後我修改了Function.prototype.apply並調用方法。所以,而不是我的功能代碼正在工作我正在運行我的攔截代碼(顯示警報)。但是「呼叫」和「應用」都不會攔截直接方法調用。攔截這個是否正確?我可以攔截直接調用的函數嗎?

Function.prototype.call = function(){alert("call");}; 
Function.prototype.apply = function(){alert("apply");}; 
function someFunction(){} 
window.onload = function(){ 
    someFunction.call(this); //call alert is shown 
    someFunction.apply(this); //apply alert is shown 
    someFunction(); //how can I intercept this? 
} 

回答

27

您只能在它的位置設置其他功能(例如,你不能攔截所有函數調用)覆蓋已知函數:

(function() { 
    // An anonymous function wrapper helps you keep oldSomeFunction private 
    var oldSomeFunction = someFunction; 

    someFunction = function() { 
     alert("intercepted!"); 
     oldSomeFunction(); 
    } 
})(); 

需要注意的是,如果someFunction已經別名/在由此代碼更改之前由另一個腳本引用,這些引用仍然指向原函數不會被替換函數覆蓋。

+0

也許我可以改變Function.constructor功能,所以每一個返回的函數將圍繞它的包裝。 – yilmazhuseyin 2010-08-04 14:36:32

+2

@yilmazhuseyin:不,你不能。更改* Function *構造函數只會允許您覆蓋使用'new Function(str)'創建的函數。 – 2010-08-04 14:49:03

+0

是的你是對的。函數newConstructor(){alert(「a」);}; Function.prototype.constructor = newConstructor; 沒有工作。 – yilmazhuseyin 2010-08-04 14:56:41

2

您可以遍歷全局作用域,並替換找到的不是「您的」的函數類型的任何對象。

3

有機會的話,你可以攔截直接功能呼叫。這就要求:

  • 無論是功能由Function.prototype.bind創建,你必須創建函數之前覆蓋Function.prototype.bind,或
  • 功能是從()的函數(或新創建函數()),並且在創建目標函數之前還必須覆蓋函數函數。

如果既沒有上述兩個可滿足,攔截直接調用的唯一方法是封裝目標函數,這是通過AndyE https://stackoverflow.com/a/3406523/1316480

提供對於由創建的函數的溶液函數文字並隱藏在私人範圍內,因此無法攔截直接調用它。

我有一個博客文章總結所有這些:http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

相關問題