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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3406467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 01:05:05  来源:igfitidea点击:

Can I intercept a function called directly?

javascript

提问by yilmazhuseyin

In this code I created a function called someFunction. Then I modified Function.prototype.apply and call methods. So instead of my function code is working I am running my interception code (which shows an alert). But neither "call" nor "apply" intercepts direct method call. Is it possiple to intercept this?

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

回答by Andy E

You can only override a known function by setting another function in its place (e.g., you can't intercept ALL function calls):

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

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

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

Note that, if someFunctionwas already aliased/referenced by another script before it was changed by this code, those references would still point to the original function not be overridden by the replacement function.

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

回答by Thomas Eding

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


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


It is worth noting that in newer versions of JS, there are Proxyobjects you can use: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

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

回答by Neal Xiong

There is a chance you can intercept direct function call. This requires:

您有机会拦截直接函数调用。这需要:

  • Either the function is created by Function.prototype.bind and you have to overwrite Function.prototype.bind before creating the function, or
  • The function is created from Function() (or new Function()) and you also have to overwrite Function function before creating the target function.
  • 要么函数是由 Function.prototype.bind 创建的,你必须在创建函数之前覆盖 Function.prototype.bind,或者
  • 该函数是从 Function() (或 new Function())创建的,您还必须在创建目标函数之前覆盖 Function 函数。

If neither of the above two can be met, the only way to intercept a direct call is to wrap the target function, which is the solution provided by AndyE https://stackoverflow.com/a/3406523/1316480

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

For a function that is created by function literal and is hidden in private scope, there is no way to intercept a direct call to it.

对于由函数字面量创建并隐藏在私有作用域中的函数,无法拦截对其的直接调用。

I have a blog post concludes all of these: http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

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

回答by jhurshman

You could iterate over the global scope and replace any objects of function type you find which aren't "yours".

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