我最近console.log
通过调用查看了萤火虫的代码console.log.toString()
并得到了这个:
function () { return Function.apply.call(x.log, x, arguments); }
只要我理解这会导致Function.apply
被调用,它的this
引用x.log
和参数是x
and arguments
。由于Function.apply
它本身调用函数,这将导致x.log
以它的this
引用x
和arguments
作为它的参数被调用。
这引出了我的问题:是否有任何理由以Function.apply
这种方式调用而不是仅使用Function.prototype.apply
?或者换句话说,上面和之间有什么区别return x.log.apply(x, arguments)
吗?
编辑:由于它是开源的,我快速查看了 firebug 源代码并找到了它的创建位置(consoleInjector.js,第 73 行):
// Construct a script string that defines a function. This function returns
// an object that wraps every 'console' method. This function will be evaluated
// in a window content sandbox and return a wrapper for the 'console' object.
// Note that this wrapper appends an additional frame that shouldn't be displayed
// to the user.
var expr = "(function(x) { return {\n";
for (var p in console)
{
var func = console[p];
if (typeof(func) == "function")
{
expr += p + ": function() { return Function.apply.call(x." + p +
", x, arguments); },\n";
}
}
expr += "};})";
// Evaluate the function in the window sandbox/scope and execute. The return value
// is a wrapper for the 'console' object.
var sandbox = Cu.Sandbox(win);
var getConsoleWrapper = Cu.evalInSandbox(expr, sandbox);
win.wrappedJSObject.console = getConsoleWrapper(console);
我现在几乎可以肯定这与Function
处于不同的范围有关,这就是我在对pst的回答的第一条评论中所说的,但我仍然不完全理解它。我可能会对此做进一步的研究。