Come ha detto Russ Cam, si evita di inquinare il namespace globale, che è molto importante in questi giorni di combinazione di script da più postazioni (TinyMCE, ecc).
Come ha detto Alex Sexton, rende anche buona organizzazione del codice.
Se si utilizza questa tecnica, suggerirei di utilizzare il modello del modulo. Questo utilizza ancora letterali oggetto, ma come valore restituito da una funzione di scoping:
var MyThingy = (function() {
function doSomethingCool() {
...
}
function internalSomething() {
....
}
function anotherNiftyThing() {
// Note that within the scoping function, functions can
// call each other direct.
doSomethingCool();
internalSomething();
}
return {
doSomethingCool: doSomethingCool,
anotherNiftyThing: anotherNiftyThing
};
})();
Uso esterno:
MyThingy.doSomethingCool();
La funzione di scoping è avvolto intorno a tutte le funzioni, e quindi si chiama subito e memorizza il suo valore di ritorno. Vantaggi:
- funzioni sono dichiarate normalmente e quindi hanno nomi. (Mentre con il formato
{name: function() { ... }}
, tutte le funzioni sono anonime, anche se le proprietà che le fanno riferimento hanno nomi.) I nomi degli strumenti di aiuto aiutano a visualizzare quale stack di chiamate in un debugger ti dice quale funzione ha generato un'eccezione. (Aggiornamento 2015: l'ultima specifica JavaScript, ECMAScript 6a edizione, definisce un gran numero di modi in cui il motore JavaScript deve dedurre il nome di una funzione. Uno di questi è quando la funzione viene assegnata a una proprietà come nell'esempio {name: function() { ... }}
. motori implementano ES6, questo motivo andrà via.)
- Ti dà la libertà di avere funzioni private utilizzate solo dal tuo modulo (come il mio
internalSomething
sopra). Nessun altro codice sulla pagina può chiamare quelle funzioni; sono veramente privati. Solo quelli che esporti alla fine, nell'istruzione return, sono visibili al di fuori della funzione scoping.
- Consente di restituire diverse funzioni in base all'ambiente, se l'implementazione cambia completamente (ad esempio materiale IE-vs-W3C o SVG o Canvas, ecc.).
Esempio di restituzione diverse funzioni:
var MyUtils = (function() {
function hookViaAttach(element, eventName, handler) {
element.attachEvent('on' + eventName, handler);
}
function hookViaListener(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
}
return {
hook: window.attachEvent ? hookViaAttach : hookViaListener
};
})();
MyUtils.hook(document.getElementById('foo'), 'click', /* handler goes here */);
fonte
2009-10-21 11:25:40
Quando installi una funzione in modo "anonimo", puoi comunque assegnargli un nome (var x = function x() {...}). Quando lo fai, il nome viene associato in modo tale che sia disponibile per i riferimenti ricorsivi all'interno della funzione. – Pointy
@Pointy: non è possibile farlo (utilizzare un nome di funzione all'interno di un compito) cross-browser, non funziona correttamente su IE o Safari; dettagli: http://yura.thinkweb2.com/named-function-expressions/ E non è necessario, il nome proprio della funzione (il 'foo' in' function foo') è in-scope nell'intero ambito in cui è dichiarato, incluso all'interno della funzione stessa, quindi 'foo' può chiamarsi tramite il simbolo' foo', non è necessario assegnare il riferimento alla funzione a qualcosa (in quel punto). –
(continua) Certo, sarebbe * bello * essere in grado di utilizzare contemporaneamente sia l'assegnazione sia il nome proprio perché renderebbe più semplice l'esportazione di funzioni dalla funzione di ambito. Lo spec certamente lo permette, ma purtroppo, praticità (bug di implementazione) entrano in esso. –