我是否可以覆盖函数对象的行为,以便可以在每次函数调用之前注入行为,然后像往常一样继续?具体地说,(尽管总体思想本身很有趣)我是否可以将每个函数调用都记录到控制台,而不必到处插入console.log语句?然后正常的行为会继续吗?
我确实认识到这可能会有严重的性能问题;我不打算让它典型地运行,即使在我的开发环境中也是如此。但是如果它能工作,它似乎是一个优雅的解决方案,在运行的代码上获得1000米的视图。我怀疑答案会让我对javascript有更深层次的了解。
发布于 2011-03-09 17:03:50
显而易见的答案是这样的:
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
,它...
重点是,我不确定这是不可能的。
发布于 2011-03-09 18:31:05
我得到了一些结果,并且没有页面崩溃,如下所示:
(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”实际调用才会被处理
发布于 2012-09-14 21:23:45
只是一个快速的测试,但它似乎对我很有效。这种方式可能没有用,但我基本上是在替换的时候恢复原型,然后在退出之前“恢复”它。
这个例子简单地记录了所有的函数调用-尽管可能有一些致命的缺陷我还没有检测到;在喝咖啡休息的时候做这件事
实现
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中输入了以下内容:
/* example usage
* (only tested through the node.js REPL)
*/
registerOverride(myCall);
console.log("hello, world!");
removeOverride(myCall);
console.log(callLog);
https://stackoverflow.com/questions/5226550
复制相似问题