Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/414.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以重载Function.prototype.call以记录所有函数调用?_Javascript_Debugging_Prototype - Fatal编程技术网

Javascript 是否可以重载Function.prototype.call以记录所有函数调用?

Javascript 是否可以重载Function.prototype.call以记录所有函数调用?,javascript,debugging,prototype,Javascript,Debugging,Prototype,我试图更改Function.prototype.call到console.log所有函数调用(用于调试),但我的浏览器崩溃了,可能吗?如果是,代码应该是什么样子 我尝试过这样做: (function(call) { Function.prototype.call = function() { console.log(this); call.apply(this, arguments); }; })(Function.prototype.call); 但是当我把鼠标移到页

我试图更改Function.prototype.call到console.log所有函数调用(用于调试),但我的浏览器崩溃了,可能吗?如果是,代码应该是什么样子

我尝试过这样做:

(function(call) {
  Function.prototype.call = function() {
    console.log(this);
    call.apply(this, arguments);
  };
})(Function.prototype.call);

但是当我把鼠标移到页面上时,我得到了大量的
toString(){[Native code]}
,如果我称之为代码,我就需要关闭该选项卡。

我发现我由于过度日志记录而使多个浏览器崩溃。。。这听起来像是灾难的秘诀

此外,大多数(所有?)现代浏览器将该属性设置为只读,以防止第三方脚本监视系统上发生的情况

您最好使用FireFox或Chrome中的评测工具来跟踪正在发生的事情 不,不可能通过某种通用getter拦截每个函数调用

Function.prototype.call
不会在每次调用函数时调用,而是用于在调用函数时传递另一个
thisArg
,这意味着在调用函数时不会隐式调用它


最接近的方法是迭代所有全局可访问的函数或对感兴趣的函数的一系列引用,并修补每个函数

然而,这也意味着您只能截取那些您已经知道的函数。 如果函数不可全局访问,例如包含在词法环境中、对代码隐藏或在函数运行后声明,则无法捕获它

因此,尽管您可以重写单个函数,或者为其定义一个getter,但不幸的是,通常不可能拦截每个函数调用

但是,如果您想捕获通过
Function.prototype.call调用的所有函数,您确实可以覆盖它

有两件事你需要改变,才能让它起作用

  • 由于您将对象(
    this
    )传递到console.log,
    object.prototype.toString
    将该对象作为
    thisArg
    调用
    。你最终会进入一个无限循环
  • 您不会将调用的结果返回到原始的
    函数.prototype.call
    调用。它会中断依赖于此返回值的代码
  • 有鉴于此,稍微修改一下的版本应该记录函数的名称,调用是在上调用的

    (function(call) {
      Function.prototype.call = function() {
        console.log(this.toString ());
        return call.apply(this, arguments);
      };
    })(Function.prototype.call);
    

    不过。似乎您想要捕获任何名为的函数。这样做是不可能的,只有使用
    Function.prototype.call调用的函数才能被拦截。

    您正在吞咽返回值。您的前提中存在一个缺陷:每次调用函数时都不会调用
    Function.prototype.call
    函数。但我看不到崩溃:但你是在复制这个特定的崩溃吗?顺便说一句,这看起来很像一个注释。@code主要是一个注释,但是
    call
    通常是只读的,这一事实使它成为了一个“你不能那样做”的答案。你用这种方式截获了任何函数调用吗?我没有这样做,这似乎是合乎逻辑的:`Function.prototype.call`不必在每次调用函数时都被调用。不,这显然是不可能的,因为正如你所说的,
    Function.prototype.call
    如果你简单地调用一个函数就不会被调用。