2010-08-04 48 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/

相关问题