首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我可以重写Javascript函数对象来记录所有函数调用吗?

我可以重写Javascript函数对象来记录所有函数调用吗?
EN

Stack Overflow用户
提问于 2011-03-08 07:24:12
回答 5查看 26K关注 0票数 57

我是否可以覆盖函数对象的行为,以便可以在每次函数调用之前注入行为,然后像往常一样继续?具体地说,(尽管总体思想本身很有趣)我是否可以将每个函数调用都记录到控制台,而不必到处插入console.log语句?然后正常的行为会继续吗?

我确实认识到这可能会有严重的性能问题;我不打算让它典型地运行,即使在我的开发环境中也是如此。但是如果它能工作,它似乎是一个优雅的解决方案,在运行的代码上获得1000米的视图。我怀疑答案会让我对javascript有更深层次的了解。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-09 17:03:50

显而易见的答案是这样的:

代码语言:javascript
复制
var origCall = Function.prototype.call;
Function.prototype.call = function (thisArg) {
    console.log("calling a function");

    var args = Array.prototype.slice.call(arguments, 1);
    origCall.apply(thisArg, args);
};

但这实际上立即进入了无限循环,因为调用console.log的行为执行了一个函数调用,它调用了console.log,它执行了一个函数调用,它调用了console.log,它...

重点是,我不确定这是不可能的。

票数 25
EN

Stack Overflow用户

发布于 2011-03-09 18:31:05

我得到了一些结果,并且没有页面崩溃,如下所示:

代码语言:javascript
复制
(function () {
  var 
    origCall = Function.prototype.call,
    log = document.getElementById ('call_log');  

  // Override call only if call_log element is present    
  log && (Function.prototype.call = function (self) {
    var r = (typeof self === 'string' ? '"' + self + '"' : self) + '.' + this + ' ('; 
    for (var i = 1; i < arguments.length; i++) r += (i > 1 ? ', ' : '') + arguments[i];  
    log.innerHTML += r + ')<br/>';



    this.apply (self, Array.prototype.slice.apply (arguments, [1]));
  });
}) ();

仅在Chrome版本9.xxx中测试。

它当然没有记录所有的函数调用,但它记录了一些函数调用!我怀疑只有对自己的“call”实际调用才会被处理

票数 4
EN

Stack Overflow用户

发布于 2012-09-14 21:23:45

只是一个快速的测试,但它似乎对我很有效。这种方式可能没有用,但我基本上是在替换的时候恢复原型,然后在退出之前“恢复”它。

这个例子简单地记录了所有的函数调用-尽管可能有一些致命的缺陷我还没有检测到;在喝咖啡休息的时候做这件事

实现

代码语言:javascript
复制
callLog = [];

/* set up an override for the Function call prototype
 * @param func the new function wrapper
 */
function registerOverride(func) {
   oldCall = Function.prototype.call;
   Function.prototype.call = func;
}

/* restore you to your regular programming 
 */
function removeOverride() {
   Function.prototype.call = oldCall;
}

/* a simple example override
 * nb: if you use this from the node.js REPL you'll get a lot of buffer spam
 *     as every keypress is processed through a function
 * Any useful logging would ideally compact these calls
 */
function myCall() { 
   // first restore the normal call functionality
   Function.prototype.call = oldCall;

   // gather the data we wish to log
   var entry = {this:this, name:this.name, args:{}};
   for (var key in arguments) {
     if (arguments.hasOwnProperty(key)) {
      entry.args[key] = arguments[key];
     }
   }
   callLog.push(entry);

   // call the original (I may be doing this part naughtily, not a js guru)
   this(arguments);

   // put our override back in power
   Function.prototype.call = myCall;
}

用法

我遇到了一些问题,包括在一个大粘贴中调用它,所以为了测试上面的函数,我在REPL中输入了以下内容:

代码语言:javascript
复制
/* example usage
 * (only tested through the node.js REPL)
 */
registerOverride(myCall);
console.log("hello, world!");
removeOverride(myCall);
console.log(callLog);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5226550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档