我可以拦截直接调用的函数吗?

时间:2010-08-04 14:24:45

标签: javascript

在这段代码中,我创建了一个名为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?
}

4 个答案:

答案 0 :(得分:28)

您只能通过在其位置设置另一个函数来覆盖已知函数(例如,您不能拦截所有函数调用):

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

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

请注意,如果someFunction在此代码更改之前已被另一个脚本别名/引用,那么这些引用仍将指向替换函数不会覆盖的原始函数。

答案 1 :(得分:8)

Function.prototype.callWithIntercept = function () {
    alert("intercept");
    return this.apply(null, arguments);
};

var num = parseInt.callWithIntercept("100px", 10);

值得注意的是,在较新版本的JS中,您可以使用Proxy个对象: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

答案 2 :(得分:3)

你有可能拦截直接的函数调用。这需要:

  • 函数是由Function.prototype.bind创建的,你必须在创建函数之前覆盖Function.prototype.bind,或者
  • 该函数是从Function()(或新的Function())创建的,您还必须在创建目标函数之前覆盖Function函数。

如果以上两者都不能满足,拦截直接调用的唯一方法是包装目标函数,这是AndyE提供的解决方案https://stackoverflow.com/a/3406523/1316480

对于由函数文字创建并隐藏在私有范围内的函数,无法拦截对它的直接调用。

我的博客文章总结了所有这些:http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

答案 3 :(得分:2)

您可以遍历全局范围并替换您找到的不属于“您的”的任何函数类型的对象。