简体   繁体   English

Function.apply与Function.prototype.apply

[英]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和参数是xarguments 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指的是xarguments作为参数。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM