2013-02-13 11 views
5

Ich sah vor kurzem in den Code von firebugs console.log von console.log.toString() Aufruf und bekam diese:Function.apply vs. Function.prototype.apply

function() { return Function.apply.call(x.log, x, arguments); } 

Solange ich verstehe dies bewirkt, dass Function.apply mit seiner this aufgerufen werden bezogen auf x.log und die Argumente sind x und arguments. Da Function.apply selbst Funktionen aufruft, führt dies dazu, dass x.log mit seinen this bezogen auf x und arguments als Argumente aufgerufen werden.

Das führt mich zu meiner Frage: Gibt es einen Grund, Function.apply auf diese Weise statt nur Function.prototype.apply anrufen? Oder mit anderen Worten, gibt es einen Unterschied zwischen den obigen und return x.log.apply(x, arguments)?

Edit: Da es Open Source ist ich an der Firebug Quelltext einen kurzen Blick nahm und fand den Ort, an dem diese erstellt wird (consoleInjector.js, Zeile 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); 

Ich bin jetzt fast sicher, dass Das hat etwas mit Function in einem anderen Bereich zu tun, was ich in meinem ersten Kommentar zu pst 's Antwort gesagt habe, aber ich verstehe es immer noch nicht vollständig. Ich kann ein bisschen mehr darüber nachforschen.

+0

Ich bin neugierig, warum der Code nicht nur das Ergebnis von 'CU.evalInSandbox (" Funktion ", Sandbox)' in einem Standard-Ansatz (wie die Funktion-Objekte scheinbar zurückgegeben werden), aber anscheinend dort ist ein Grund ... eigentlich macht das auch nicht viel, da 'Funktion' nicht * geschlossen sein sollte; es sei denn, es gibt mehr Magie in 'evalInSandbox' .. –

Antwort

4

diese Bedenken Sie:

Function.hasOwnProperty("apply")    // false 
Function.apply == Function.prototype.apply // true 
Function.__proto__ == Function.prototype  // true in FF which exposes proto 

So Function.apply funktioniert, weil [[Prototyp]] Funktion des Function.prototype ist. In diesem Fall sollten beide wie gewünscht funktionieren.

jedoch die Ansicht, dass normale [GetProperty] Regeln gelten nach wie vor:

var f = function() {}; 
f.apply = "nubbits"; 
f.apply(/* err */); 

Zugegeben, ich würde es für „fraglich Code“, um das Verhalten von apply zu ändern (und vor allem in einer inkompatiblen Weise), aber es ist möglich, dass die beiden Formen unterscheiden .. Ich persönlich nicht solche hypothetischen Situationen unterbringen und ich verwende f.apply in meinem Code.

+0

Ich habe mich gefragt - warum wäre es dann" besser ",' Function.prototype.apply' über 'myFunc.apply' (die andere Frage des OP) zu verwenden? – Ian

+0

@Ian Vielleicht bevorzugt man die "explizite Form". Ich kann mir keinen besonderen Grund vorstellen, auf den ich in meinem Code gestoßen bin - ich bevorzuge "fn.apply". (Und wenn jemand ändert, was es tut, dann ist das auf ihnen ..) –

+0

Also würde dies nur getan werden, um eine der Änderungen des Verhaltens von 'console.log.apply' zu stoppen? Daran kann man nicht denken, dass dies der einzige Grund ist ... Ich denke auch, dass dies gemacht werden könnte, weil "Function" (die Funktion, auf die sich 'apply' bezieht) in einem anderen Bereich liegt, der höchstwahrscheinlich der Problem hier: http://stackoverflow.com/questions/14715140/why-does-prototyping-function-not-affecto-console-log – YingYang

Verwandte Themen