2012-07-18 13 views
5

Proprio controllando il codice JavaScript di Google e ho trovato questa sintassi:sintassi JavaScript (0, fn) (args)

var myVar = function...; 
(0, myVar)(args); 

Non si conosce il significato di questa sintassi? Non riesco a trovare la differenza tra (0, myVar)(args); e myVar(args);.

Per fare un esempio esatto, abbiamo

_.x3 = function (a, b) { 
    return new _.q3(20 * b.x + a.B.B.x, 20 * b.y + a.B.B.y) 
}; 

E più tardi

this.ta = new _.s3((0, _.x3)(this.fa, this.B.B), 0); 
+0

possibile duplicato del [javascript virgola operator] (http://stackoverflow.com/questions/5580596/javascript-comma-operator) –

+0

Per curiosità, puoi pubblicare più dello contesto di dove appare? – Austin

+0

Stavo controllando il codice di https://www.google.fr/xjs/_/js/s/sy46,zr/rt=j/ver=-wnZQEUYm8E.en_US./d=0/rs=AItRSTNMBUOhWluxPqsKFY9CVTnMlxNz6w – korko

risposta

0

L'operatore virgola restituisce il valore dell'ultima operando, in modo che il valore del 0, myVar è lo stesso valore di myVar. Il valore del primo operando viene valutato, ma in questo caso ovviamente non realizza nulla.

L'operatore virgola viene utilizzato a volte, quando il primo operando in realtà fa qualcosa, come l'inizializzazione due variabili in un ciclo:

for (i = 0, j = 42; i < 10; i++, j--) ... 
+0

Sì, lo so, ma la ragione è in realtà qual è l'interesse di questo (0, fn)? Se ne conosci qualcuno? Forse è solo un segnaposto per casi specifici, ma non penso che Google aggiungerà caratteri inutili nel loro js. – korko

+1

@korko: Non c'è una ragione pratica per questo costrutto, quindi è un malinteso o un tentativo di offuscare il codice. – Guffa

+0

Non credo che Google stia fraintendendo javascript: D Quindi forse offusca ma non penso nemmeno, aggiunge solo alcuni caratteri mentre Google cerca sempre di rimuovere i caratteri inutili per ridurre le dimensioni del file. – korko

3

Questa sintassi utilizza l'operatore virgola, ,. Valuta tutti i suoi operandi e restituisce il valore dell'ultimo. In questo caso, 0 viene utilizzato solo come segnaposto, pertanto (0, function() {}) restituirà (function() {}). Dopo averlo valutato, la parte (args) sta richiamando la funzione e gli assegna i suoi argomenti.

Edit dopo il commento:

La ragione si potrebbe usare questo stile di codifica è in modo che possano eseguire il codice rapidamente o su una sola riga. Ecco un esempio:

var a = 0, 
    b = 1, 
    c; 

c = (a++, b++, a + 2); // a is added, b is added, and a is added then returned 

a; // 1 
b; // 2 
c; // 3 
+0

Sì, assolutamente una buona ragione ma ... 0 significa niente. Esiste un qualche tipo di protezione, descoping o qualcosa che dà un significato per (0, fn)() invece di solo fn(). – korko

+0

Scusa, ma non riesco a pensare a nessuno. Sono sicuro che c'è un motivo se Google lo sta usando. – 0x499602D2

+0

Comunque, grazie per la tua risposta, è una buona cosa sapere;) – korko

1

Ho avuto la stessa domanda e poi trovato la risposta, come segue:

E 'davvero per

(0, foo.fn)(); 

Ricordate che in JavaScript, quando foo.fn() viene richiamato , quindi all'interno di fn, lo this è associato a foo. Se si utilizza

var g = foo.fn; 
g(); 

poi quando g viene richiamato in precedenza, il this è legato all'oggetto globale (window, nel contesto di un browser web).

Quindi è necessario definire g come sopra? Puoi fare qualcosa come

(foo.fn)(); 

La risposta è no. JavaScript lo considererà lo stesso di foo.fn(); in quanto è solo foo.fn con il ridondante () che può essere rimosso.

Ma c'è un modo per aggirare è, ed è esattamente da usare the comma operator, which Mozilla stated as

L'operatore virgola valuta ciascuno dei suoi operandi (da sinistra a destra) e restituisce il valore dell'ultima operando

Quindi, utilizzando

(0, foo.fn)(); 

il (0, foo.fn) otterrà valutati per un riferimento alla funzione, lik e g sopra, e quindi la funzione è invocata. E quindi, this non è associato a foo ma è associato all'oggetto globale.

Quindi il codice scritto in questo modo consiste nel "tagliare l'associazione".

Esempio:

var foo = { 
       fullName: "Peter", 
       sayName: function() { console.log("My name is", this.fullName); } 
      }; 

window.fullName = "Shiny"; 

foo.sayName();  // My name is Peter 

(foo.sayName)();  // My name is Peter 

(0, foo.sayName)(); // My name is Shiny