2010-03-11 14 views
53

Sto provando a leggere la fonte Prototype. Sono arrivato a questa parte. (Sfortunatamente, questo frammento è all'inizio).Cosa fanno le parentesi vuote() dopo una dichiarazione di funzione in javascript?

Cosa significa questo()?

Browser: (function(){ 
    var ua = navigator.userAgent; 
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; 
    return { 
     IE:    !!window.attachEvent && !isOpera, 
     Opera:   isOpera, 
     WebKit:   ua.indexOf('AppleWebKit/') > -1, 
     Gecko:   ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, 
     MobileSafari: /Apple.*Mobile.*Safari/.test(ua) 
    } 
    })(), 

Mi riferisco all'ultima riga prima della virgola?

+1

Nota: secondo JSLint si dovrebbe spostare i parenthese esecuzione finali all'interno delle parentesi delle funzioni: '(function() {...}()) ' – ErikE

+0

@ErikE Alla fine fanno la stessa cosa, però. Vedi questa domanda: http://stackoverflow.com/questions/6645766/why-are-parenthesis-used-to-wrap-a-javascript-function-call –

+0

Nessun argomento che facciano la stessa cosa. È una considerazione stilistica, perché non mettendo le parentesi di esecuzione all'interno della coppia esterna, non è chiaro che ciò che viene restituito sia il * risultato * della funzione piuttosto che * la funzione stessa *. – ErikE

risposta

40

Il codice è la definizione di una funzione anonima (la (function(){ ... }) bit) e quindi chiamando lo (senza argomenti). Assegna quindi il valore alla proprietà Browser dell'oggetto che è presumibilmente definita al di fuori dello snippet di codice.

Si potrebbe anche definire la funzione da qualche parte:

function myFunction() { 
    var ua = navigator.userAgent; 
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; 
    return { 
     IE:    !!window.attachEvent && !isOpera, 
     Opera:   isOpera, 
     WebKit:   ua.indexOf('AppleWebKit/') > -1, 
     Gecko:   ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, 
     MobileSafari: /Apple.*Mobile.*Safari/.test(ua) 
} 

e poi chiamarlo:

var foo = myFunction(); 

e quindi assegnare il valore:

... 
Browser: foo, 
... 

Uno svantaggio nel fare in modo che il modo è che "inquini il tuo spazio dei nomi" con una funzione e una variabile che non userai da nessun'altra parte . Il secondo problema è che non è possibile utilizzare il valore di qualsiasi variabile con ambito locale nella definizione della funzione (la funzione anonima si comporta come una chiusura).

5

È una semplice chiamata di funzione, non diversa da foo() eccetto che sta invocando una funzione anonima letterale, il risultato della funzione è assegnato alla proprietà Browser.

11

chiama la funzione anonima appena dichiarata, causando effettivamente la valutazione del "blocco".

27

(function() {}) crea una funzione anonima.

L'aggiunta del () alla fine chiama la funzione appena creata.

Nel caso di questa particolare funzione, la funzione anonima restituisce diverse proprietà all'oggetto Browser. Così, si finisce con i valori booleani per, ad esempio, Browser.IE, Browser.Opera, ecc

+2

Qual è la notazione corretta? '(function() {}());' OR '(function() {})();' - Sto parlando dell'ordine delle parentesi alla fine. – ayjay

+2

il tuo primo è giusto @ayjay – Jonesopolis

+2

@ayjay In realtà, uno dei due ha ragione, ma Crockford usa il primo, quindi andrei con quello. [Http://javascript.crockford.com/code.html](http://javascript.crockford.com/code.html) – GFoley83

Problemi correlati