[英]Function.apply vs. Function.prototype.apply
I recently looked into the code of firebugs console.log
by calling console.log.toString()
and got this: 我最近通过调用console.log.toString()
查看了firebugs console.log
的代码并得到了这个:
function () { return Function.apply.call(x.log, x, arguments); }
As long as I understand this causes Function.apply
to be called with its this
referring to x.log
and the arguments being x
and arguments
. 只要我明白这会导致Function.apply
与它被称为this
指的是x.log
和参数是x
和arguments
。 Since Function.apply
itself calls functions this will result in x.log
to be called with its this
referring to x
and arguments
as its arguments. 由于Function.apply
本身调用的函数,这将导致x.log
与它被称为this
指的是x
和arguments
作为参数。
Which leads me to my question: Is there any reason to call Function.apply
this way instead of just using Function.prototype.apply
? 这引出了我的问题:有没有理由以这种方式调用Function.apply
而不是仅使用Function.prototype.apply
? Or in other words, is there any difference between the above and return x.log.apply(x, arguments)
? 或者换句话说,上面和return x.log.apply(x, arguments)
之间有什么区别吗?
Edit: Since it's open source I took a quick look at the firebug sourcecode and found the place where this is created ( consoleInjector.js , line 73): 编辑:由于它是开源的,我快速查看了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);
I'm almost sure now that this has something to do with Function
to be in a different scope, which is what I sayed in my first comment to pst 's answer, but I still don't fully understand it. 我现在几乎可以肯定,这与Function
处于不同的范围有关,这是我在第一次评论pst的答案时所说的,但我仍然不完全理解它。 I may do a bit further research about that. 我可以对此进行一些进一步的研究。
Consider this: 考虑一下:
Function.hasOwnProperty("apply") // false
Function.apply == Function.prototype.apply // true
Function.__proto__ == Function.prototype // true in FF which exposes proto
So Function.apply works because Function's [[prototype]] is Function.prototype . 所以Function.apply可以工作,因为Function的[[prototype]]是Function.prototype 。 In this case both ought to work as desired. 在这种情况下,两者都应该按照需要工作。
However, consider that normal [GetProperty] rules still apply: 但是,请考虑正常的[GetProperty]规则仍然适用:
var f = function () {};
f.apply = "nubbits";
f.apply(/* err */);
Granted, I'd consider it "questionable code" to change the behavior of apply
(and especially in an incompatible manner), but it's possible that the two forms differ .. Personally, I do not accommodate such hypothetical situations and I use f.apply
in my code. 当然,我会认为这是“有问题的代码”,以改变行为apply
(尤其是在不兼容的方式),但它可能是这两种形式的不同。个人,我也不适应这种假设的情况,我用f.apply
我的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.