Perché definire una funzione anonima e passarla a jQuery come argomento?

Sto guardando l’eccellente codice demo peepcode dagli screencast di backbone.js. In esso, il codice backbone è tutto racchiuso in una funzione anonima che ha passato l’object jQuery:

(function($) { // Backbone code in here })(jQuery); 

Nel mio codice backbone, ho appena avvolto tutto il mio codice nell’evento ‘ready’ del jQuery DOM:

 $(function(){ // Backbone code in here }); 

Qual è il punto / vantaggio del primo approccio? In questo modo crea una funzione anonima che viene quindi eseguita immediatamente con l’object jQuery passato come argomento della funzione, garantendo in modo efficace che $ sia l’object jQuery. È questo l’unico punto: garantire che jQuery sia vincolato a ‘$’ o ci sono altri motivi per farlo?

I due blocchi di codice che hai mostrato sono drammaticamente diversi in quando e perché vengono eseguiti. Non sono esclusivi l’uno dell’altro. Non hanno lo stesso scopo.

Moduli JavaScript

 (function($) { // Backbone code in here })(jQuery); 

Questo è un modello “Modulo JavaScript”, implementato con una funzione che richiama immediatamente.

Lo scopo di questo codice è di fornire “modularità”, privacy e incapsulamento per il tuo codice.

L’implementazione di questa funzione è immediatamente invocata dalla parentesi chiamata (jQuery) . Lo scopo di passare jQuery in parentesi è quello di fornire l’ambito locale alla variabile globale. Ciò aiuta a ridurre il sovraccarico di ricerca della variabile $ e consente in alcuni casi una migliore compressione / ottimizzazione per i minifiers.

Le funzioni di richiamo immediato vengono eseguite, bene, immediatamente. Non appena la definizione della funzione è completa, la funzione viene eseguita.

La funzione “DOMReady” di jQuery

Questo è un alias della funzione “DOMReady” di jQuery: http://api.jquery.com/ready/

 $(function(){ // Backbone code in here }); 

La funzione “DOMReady” di jQuery viene eseguita quando il DOM è pronto per essere manipolato dal codice JavaScript.

Moduli vs DOMReady In codice Backbone

È una ctriggers forma definire il codice Backbone all’interno della funzione DOMReady di jQuery e potenzialmente dannoso per le prestazioni dell’applicazione. Questa funzione non viene chiamata fino a quando il DOM non viene caricato ed è pronto per essere manipolato. Ciò significa che stai aspettando che il browser abbia analizzato il DOM almeno una volta prima di definire i tuoi oggetti.

È un’idea migliore per definire gli oggetti Backbone al di fuori di una funzione DOMReady. Io, tra molti altri, preferisco farlo all’interno di un modello di modulo JavaScript in modo da poter fornire incapsulamento e privacy per il mio codice. Tendo ad usare il pattern “Revealing Module” (vedi il primo link sopra) per fornire l’accesso ai bit di cui ho bisogno al di fuori del mio modulo.

Definendo gli oggetti al di fuori della funzione DOMReady e fornendo un modo per fare riferimento a questi, si consente al browser di ottenere un vantaggio sull’elaborazione del codice JavaScript, velocizzando potenzialmente l’esperienza dell’utente. Rende anche il codice più flessibile in quanto è ansible spostare le cose senza doversi preoccupare di creare più funzioni DOMREADY quando si spostano le cose.

Probabilmente utilizzerai una funzione DOMReady, anche se definisci gli oggetti Backbone da qualche altra parte. La ragione è che molte app Backbone hanno bisogno di manipolare il DOM in qualche modo. Per fare ciò, è necessario attendere che il DOM sia pronto, quindi è necessario utilizzare la funzione DOMReady per avviare l’applicazione dopo che è stata definita.

Puoi trovare molti esempi di questo in giro per il web, ma ecco una implementazione molto semplice, utilizzando sia un modulo che la funzione DOMReady:

 // Define "MyApp" as a revealing module MyApp = (function(Backbone, $){ var View = Backbone.View.extend({ // do stuff here }); return { init: function(){ var view = new View(); $("#some-div").html(view.render().el); } }; })(Backbone, jQuery); // Run "MyApp" in DOMReady $(function(){ MyApp.init(); }); 

Come sidenote minore, l’invio di $ come argomento a una funzione anonima rende $ locale a quella funzione che ha una piccola implicazione di prestazioni positive se la funzione $ è chiamata molto. Questo perché javascript cerca prima l’ambito locale per le variabili e poi attraversa tutto il percorso verso l’ambito della finestra (dove vive solitamente $).

Garantisce che puoi sempre usare $ all’interno di quella chiusura anche se è stato utilizzato $.noConflict() .

Senza questa chiusura dovresti usare jQuery invece di $ tutto il tempo.

È per evitare un potenziale conflitto della variabile $. Se qualcos’altro definisce una variabile chiamata $, il tuo plugin può usare la definizione sbagliata

Fare riferimento a http://docs.jquery.com/Plugins/Authoring#Getting_Started per ulteriori dettagli

Usali entrambi.

La funzione auto-invocazione in cui si passa in jQuery per evitare conflitti di libreria e per assicurarsi che jQuery sia disponibile come ci si aspetterebbe da $.

E il metodo scorciatoia .ready () come richiesto per eseguire javascript solo dopo che il DOM ha caricato:

 (function($) { $(function(){ //add code here that needs to wait for page to be loaded }); //and rest of code here })(jQuery);