2014-09-20 2 views
7

Sto leggendo il libro di Douglas Crockford "Javascript: The Good Parts". Si sta parlando di portata e dicendo che JS non ha blocchi portata:I vantaggi di dichiarare le variabili nella parte superiore del corpo della funzione in JavaScript

In molte lingue moderne, si raccomanda che le variabili essere dichiarate il più tardi possibile, al primo punto di utilizzo. Questo risulta essere il cattivo consiglio per Javascript perché manca l'ambito del blocco. Pertanto, è preferibile dichiarare tutte le variabili utilizzate in una funzione nella parte superiore dello del corpo della funzione.

Tuttavia, non ho potuto pensare ad un buon esempio perché questa affermazione ha senso e sarebbe davvero bello vedere alcuni esempi che verificano questa affermazione.

+0

Pensate 'loop for' nello stesso ambito, utilizzando il stessa variabile 'i'. Dichiarare "i" prima e riutilizzarlo sembra più corretto o idiomatico. – elclanrs

+0

Se lo si dichiara con var, sarà locale nell'ambito. Se no, sarà globale. Quindi per chiarire che la var è locale, dichiararla esplicitamente all'inizio della funzione – mplungjan

+0

Dichiarare le variabili nella parte superiore della funzione come mezzo per documentare tutte le variabili utilizzate in un posto. Evita anche la confusione derivante da qualcuno che immagina che una variabile abbia un ambito di blocco quando invece non lo è. –

risposta

6

dichiarare le variabili in alto aiuta a evitare situazioni come questa:

function outer() { 
    var i = 50; 

    function inner() { 
    alert(i); 
    var i= 30; 
    } 
    inner(); 
} 

outer(); 

Molte persone si aspettano l'avviso per mostrare 50, e sarebbero sorpresi di vedere undefined. Questo perché la variabile i è dichiarata all'interno della funzione inner, ma non è inizializzata fino a dopo lo alert. Quindi ha un ambito di funzioni completo, anche se è dichiarato dopo il suo uso iniziale.

+0

È un esempio semplicistico, ma 'i' è una variabile di ciclo comune. Un programmatore C potrebbe vedere 'for (var i = ...)' e erroneamente pensa che 'i' abbia un ambito di blocco. Dichiarare le variabili in cima può aiutare a mantenere la leggibilità e la manutenibilità, ma devo ammettere che raramente dichiaro variabili di ciclo prima dell'uso. –

+2

Giusto per chiarire, questo è dovuto al sollevamento in modo che la funzione interna sia effettivamente 'var i; alert (i); i = 30; ' – Assaf

+0

corretto. Il termine "sollevamento" non mi è venuto in mente fino a dopo aver visto il post di @ torazaburo. –

0

Dal mio punto di vista, dato che javascript non ha scope di blocco, dichiarare tutte le variabili in cima alla funzione ti fa individuare variabili più facili che non devi usare come puoi riutilizzare un altro.

Esempio:

function test(){ 
    var pages = [ 
     'www.stackoverflow.com', 
     'www.google.com' 
    ]; 

    var users = [ 
     'John', 
     'Bob' 
    ]; 

    for (var page = 0; page < pages.length; page++) { 
     console.log(pages[page]); 
    }; 

    for (var user = 0; user < users.length; user++) { 
     console.log(users[user]); 
    }; 
} 

può essere cambiato in:

function test(){ 
    var index, pages, users; 

    pages = [ 
     'www.stackoverflow.com', 
     'www.google.com' 
    ]; 

    users = [ 
     'John', 
     'Bob' 
    ]; 

    for (index = 0; index < pages.length; index++) { 
     console.log(pages[index]); 
    }; 

    for (index = 0; index < users.length; index++) { 
     console.log(users[index]); 
    }; 
} 

e salvare uno spazio variabile dalla memoria.

In una funzione così piccola, il punto principale potrebbe non essere visibile, ma immaginare un intero progetto con migliaia di righe di codice. Questo potrebbe rendere il tuo codice più veloce.

+0

Non dovresti ora rimuovere 'var' dai tuoi cicli' for'? –

+0

sì, hai ragione grazie – GramThanos

+0

Potrebbe essere un po 'correlato, ma ancora non penso che sia la ragione del perché Douglas lo consiglia. Se questo è il caso, dovremmo farlo tutto il tempo anche nelle lingue moderne. – Tarik

3

Dichiarare le variabili nella parte superiore della funzione come mezzo per documentare tutte le variabili utilizzate in un'unica posizione.

evita anche confusione derivante da qualcuno immaginare che una variabile è block-scope quando di fatto non è, come il seguente:

var i=0; 
if (true) { 
    var i=1; 
} 
// what is i? C programmer might imagine it's 0. 

Se le variabili sono anche essere inizializzati quando viene dichiarato, mettendo la dichiarazioni in alto evita potenziali problemi con i tempi di inizializzazione:

console.log(foo); 
var foo = 1; 

In questo caso, viene issata foo quindi è dichiarato al momento della console.log, ma non è stata ancora inizializzata. Quindi questo è effettivamente come

var foo; 
console.log(foo); // no ReferenceError, but undefined 
foo = 1; 
+0

Mi piace molto questa risposta. – Tarik

0

Non è sempre una buona idea. Dipende da cosa stai facendo. Cosa significano quando dicono che non è necessario dichiarare le variabili "top level", è che non ha importanza. Può importare all'interno di una funzione.Prendere in considerazione i seguenti esempi:

varOne = 1; varTwo = 2; varThree = 3; // undeclared 
function lameFunc(){ 
    var varOne = 'Something'; // does no affect varOne at the top level 
    return varOne; 
} 

Uguale:

var varOne = 1, varTwo = 2, varThree = 3; // declared 
function lameFunc(){ 
    var varOne = 'Something'; // does no affect varOne at the top level 
    return varOne; 
} 

Certo, è più facile vedere le variabili con la parola chiave var e dal momento che non ci sono effetti avversi al "top level", si raccomanda.

Si noti che quando cambio lameFunc() si influisce sulla leva superiore var, in entrambi i casi.

function lameFunc(){ 
    /* varOne is effected at the higher level whether or not `var` is declared 
    above as in `varOne = 1` or `var varOne = 1` */ 
    varOne = 'Something'; 
    return varOne; 
} 

Inoltre, se si dichiara una variabile al di fuori della manifestazione come var someInputVal = document.getElementById('someInput').value;, allora diciamo che si desidera ottenere il valore onclick di un elemento. Vorresti che lovenga dichiarato all'interno dello perché l'input potrebbe essere stato modificato prima di aver fatto clic su Element. Esso può essere giusto per dichiarare var someInput = document.getElementById('someInput'); al di fuori della funzione che gestisce il vostro evento, se l'elemento non diventa undefined allora si può accedere simili:

var doc = document, bod = doc.body; 
function E(e){ 
    return doc.getElementById(e); 
} 
var someInput = E('someInput'), someInputVal = someInput.value; 
E('clickButton').onclick = function(){ 
    console.log(someInputVal); // will not be what document.getElementById('someInput').value is if it was changed before clicking 
    var declared = someInput.value; 
    console.log(declared); 
}