2010-08-29 8 views
40

Molto tempo fa, ho visto qualcuno incapsulare l'intero blocco di JavaScript con il codice di qualcosa come il codice qui sotto:incapsulamento in JavaScript

(function() { 
    // ... 
})(this); 

Domande:

  1. è il codice di cui sopra è corretto?
  2. Che vantaggio c'è per incapsulare l'intero blocco JavaScript come indicato sopra?
+1

Penso che "incapsulare" sia un termine fuorviante e che debba essere modificato in "ambito" per quanto riguarda i concetti OOP –

risposta

75

Sì, è corretto. Si chiama un'espressione di funzione anonima auto-invocante.

Le variabili JavaScript hanno uno scope di funzione o ambito globale. Non esiste un ambito di blocco. Includendo il codice in una funzione auto-invocante come quella dell'esempio, viene creato un ambito locale temporaneo per il codice a esecuzione immediata monouso, senza inquinare lo spazio dei nomi globale.

Si consideri il seguente:

<html> 
<body> 
... 
<script> 
    (function() { 
     var x = ''; 

     function myFunction() { 
     alert('Hello: ' + x); 
     } 

     x = 'Bob'; 
     myFunction(); 

     alert(typeof x);   // string 
     alert(typeof myFunction); // function 
    })(); 

    alert(typeof x);    // undefined 
    alert(typeof myFunction);  // undefined 
</script> 
<script src="other-javascript.js"></script> 
</body> 
</html> 

Qualunque cosa si dichiara in quella funzione di auto invocando si svolge in un ambito separato. La variabile x e la funzione myFunction() non sono accessibili da nessun'altra parte. Il codice in other-javascript.js non li vedrà, ad esempio, e sarebbe libero di dichiarare un'altra funzione myFunction() senza conflitti.

+1

Quindi l'ambito del "blocco" è una variabile privata? – nickb

+0

@ user434493: A differenza di C, C++, Java e altri linguaggi, la variabile 'y' in' if (x> 5) {var y = 0; } 'è possibile accedere dall'esterno del blocco' if' ...Quello sarebbe stato un ambito di blocco, ma le variabili JavaScript sono memorizzate in un ambiente di funzione e non sono influenzate da altri blocchi '{}'. Consentitemi di aggiornare la mia risposta con un esempio ... –

+3

Come impostare una variabile dall'esterno dell'incapsulamento a un oggetto dall'interno dell'incapsulamento? – user3015682

32

anche aggiunta alla risposta @ di Daniel, passando this alla funzione è un modello comune per avere un riferimento all'oggetto globale, ad esempio:

(function(window){ 

})(this); 

nel browser scripting l'oggetto globale ha una proprietà denominata window che si riferisce all'oggetto globale stesso, in altri ambienti non esiste la proprietà window.

Inoltre, un'altra cosa che si può fare è quello di specificare un argomento di nome undefined, perché la proprietà undefined non è descritto sul ECMAScript 3 °. Standard Edition (non v'è alcuna garanzia che esiste o non), in alcune implementazioni la proprietà è mutabile, ad esempio:

(function(window, undefined){ 

})(this); 

Nel precedente esempio, abbiamo due identificatori locali (che sono un po 'più veloce per risolvere), window e undefined, viene passato solo il primo (this, che fa sempre riferimento all'oggetto globale in Codice globale (codice che è esterno a qualsiasi funzione)), e il secondo, conterrà il valore primitivo undefined , perché non stiamo passando alcun valore ad esso.

Questo modello è utilizzato da alcune librerie come jQuery.