2009-08-05 11 views
49

Ho usato JSLint per farmi stare male con il mio JavaScript. A proposito, è fantastico. C'è un assegno che non capisco e vorrei i tuoi punti di vista, per favore.Una var per funzione in JavaScript?

Da jslint.com:

In linguaggi con ambito blocco, si raccomanda di solito che le variabili essere dichiarate presso il sito del primo utilizzo. Ma poiché JavaScript non ha scope di blocco, è più saggio dichiarare tutte le variabili di una funzione nella parte superiore della funzione. Si consiglia di utilizzare una singola istruzione var per ogni funzione.

Qual è l'ultima frase in grassetto che dice davvero? Penso che dovrei dichiarare più variabili come questa?

var foo = 1, bar = 2; 

E, è la parte "saggio" solo uno stile di programmazione per scoraggiare gli errori su tutta la linea o c'è di più ad esso che quello?

Grazie per il vostro aiuto.

+0

Ho ricevuto due risposte superbe da http://stackoverflow.com/users/5445/cms e http://stackoverflow.com/users/51101/breton. Sento che entrambi rispondono a questa domanda. Come posso dare credito ad entrambi? :( –

+7

A proposito, se vuoi davvero stare male con il tuo codice, prova a leggere il codice sorgente su JSLINT e capire come funziona. È perfettamente chiaro e leggibile, eppure ancora misterioso. È come scoprire che l'universo è un frattale calcolato dall'equazione 2 + 2 =? – Breton

+0

Qualcuno non di uno strumento che riformatterà automaticamente il codice allo stile var per funzione? (ma non minimizza) – jlarson

risposta

71

Il problema è che, indipendentemente dal fatto che lo realizzi o meno, javascript sposta in modo invisibile tutte le dichiarazioni var in cima all'ambito della funzione.

quindi se avete una funzione come questa

var i = 5; 
function testvar() { 
    alert(i); 
    var i=3; 
} 
testvar(); 

la finestra di avviso conterrà indefinito. perché internamente, è stato modificato in questo:

var i = 5; 
function testvar() { 
    var i; 
    alert(i); 
    i=3; 
} 
testvar(); 

questo è chiamato "sollevamento". La ragione per cui crockford sostiene con forza le dichiarazioni var in cima, è che rende il codice visibilmente corrispondente a quello che sta per fare, invece di permettere che si verifichino comportamenti invisibili e imprevisti.

+0

Interessante - non lo sapevo davvero su JS - naturalmente, di solito definisco tutte le mie variabili in cima comunque, e riusciamo raramente a usare un nome di variabile da un loop esterno/funzione. – gnarf

+0

Questo è interessante, ma non è strettamente correlato all'ambito del blocco. – Triptych

+0

Ma è una risposta valida alla mia domanda ... –

8

Fondamentalmente in blocchi JavaScript ({ ... }) non introducono un nuovo ambito, esiste solo la funzione-ambito, quindi non viene creato alcun ambito su alcuna altra istruzione.

Una variabile introdotta ovunque in una funzione è visibile ovunque nella funzione.

Ad esempio:

function myFunction(){ 
    var one = 1; 

    if (one){ 
    var two = one + 1; 
    } 

    (function() { 
    var three = one + two; 
    })(); 

    // at this point both variables *one* and *two* are accessible but 
    // the variable *three* was declared in the scope of a inner function 
    // and is not accessible at this point. 
} 

In linguaggi con ambito blocco, raccomanda di dichiarare le variabili in corrispondenza del punto di primo utilizzo, ma dal momento che JavaScript non ha scopo di blocco, è meglio dichiarare tutto ad un le variabili della funzione nella parte superiore della funzione.

Controllare questo article.

+2

In realtà non si spiega perché sia ​​meglio, ma alla fine segue solo la funzione che è meglio che i vars siano al top, ma hai lasciato fuori i passaggi di ragionamento da questo fatto, alla tua conclusione. – Breton

+3

Ho appena letto l'articolo a cui ti sei collegato, e commette lo stesso errore di Chetan. redeclaring a var è un NOOP. È completamente benigno e non causa alcun problema. Questo non vuol dire che limitarsi a una dichiarazione var è inutile, ma tu, né l'articolo, ne hai fatto un caso convincente. – Breton

+0

@Breton, può causare problemi perché è spesso un riflesso di un programmatore confuso. Può anche confondere altri programmatori che fanno la cosa sensata e mettono tutti i vars nella parte superiore della funzione. – Nosredna

4

Sì, significa che si dichiarano tutte le variabili all'inizio della funzione. Se vuoi farlo in una riga o più righe è una questione di scelta.

Il motivo è spiegato nel paragrafo che hai citato. Le variabili Javascript hanno solo un ambito a livello di funzione. Se dichiari la stessa variabile all'interno di un blocco if/while/for, verrà sovrascritta dal nuovo valore poiché il blocco non ha un nuovo ambito. Questo è diverso da lingue come Java. Per evitare tali sorprese, dichiarare tutte le variabili che si intende utilizzare nella funzione all'inizio della funzione in modo da non riscrivere accidentalmente "andything".

+0

Non penso che la ridichiarazione di una variabile sia il problema. Questo non genera un errore come fa in C (o java?). In effetti non fa nulla. – Breton

+0

Scusa, devo essere stato più chiaro. Quello che intendevo era dichiarare lo stesso nome di variabile all'interno di un blocco, che è permesso in Java. Questa nuova variabile vive solo all'interno del blocco. –

+0

Ah sì, suppongo che sarebbe un problema se foste abituati a una lingua con ambito di blocco. – Breton

6

La mancanza del campo di applicazione blocco spiega il codice qui sotto:

var a = 1; 
if (something) { 
    var a = 2; 
} 

alert(a); // Alerts "2" 

Nella maggior parte in stile C (come nella sintassi) lingue, la definizione var a = 2 definirebbe 'a' solo per il campo di applicazione del blocco if. L'uso di una singola istruzione var nella parte superiore della funzione aiuta a evitare questo cavillo di Javascript, che non è sempre ovvio come sopra, e sarebbe inaspettato per i programmatori C/C#/Java.

Problemi correlati