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

xesrikrc  于 2023-01-19  发布在  Java
关注(0)|答案(6)|浏览(155)

在这段代码中,我创建了一个名为someFunction的函数。然后我修改了Function.prototype.apply和call方法。因此,我的函数代码没有工作,而是运行了拦截代码(显示了一个警报)。但是“call”和“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?
}
k7fdbhmy

k7fdbhmy1#

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

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

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

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

mctunoxg

mctunoxg2#

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

laik7k3q

laik7k3q3#

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

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

如果以上两个条件都不满足,拦截直接调用的唯一方法就是 Package 目标函数,这是AndyE https://stackoverflow.com/a/3406523/1316480提供的解决方案
对于由函数文本创建并隐藏在私有作用域中的函数,无法拦截对其的直接调用。
我有一篇博客文章总结了所有这些:http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

mlnl4t2r

mlnl4t2r4#

您可以遍历全局作用域,并替换您发现的任何不属于“您的”函数类型的对象。

bqujaahr

bqujaahr5#

太棒了,喜欢它:)

const originalApply = window.Function.prototype.apply;
window.Function.prototype.apply = function(){
    console.log("INTERCEPTING APPLY", arguments);
    return originalApply.call(this, ...arguments);
};
j2qf4p5b

j2qf4p5b6#

您可以使用Proxy来实现这一点。
首先定义一个带有apply陷阱的处理程序,该陷阱用于拦截对函数的调用。然后,使用该处理程序,将函数设置为自身的代理。示例:

function add(a, b){
  return a + b;
}

const handler = {
  apply: function(target, thisArg, argumentsList) {
    console.log('add was called with ' + argumentsList.join(' and '));
    return target(...argumentsList);
  }
};

add = new Proxy(add, handler);

var m = add(3, 5);
console.log('m = ', m);

var n = add(12, 8);
console.log('n = ', n);

相关问题