2013-03-26 9 views
12

Prima di porre la mia domanda, lasciatemi dare una dichiarazione di non responsabilità. So cosa fa lo var, conosco l'ambito dei blocchi, e so di sollevamento variabile. Non sto cercando risposte su questi argomenti.Esistono lati negativi per l'utilizzo di var più di una volta sulla stessa variabile in JavaScript

Mi chiedo semplicemente se esiste un costo funzionale, di memoria o di prestazioni per l'utilizzo di una dichiarazione di variabile sulla stessa variabile più di una volta all'interno di una funzione.

Ecco un esempio:

function foo() { 
    var i = 0; 
    while (i++ < 10) { 
    var j = i * i; 
    } 
} 

Il precedente, potrebbero semplicemente potuto facilmente stato scritto con l'j variabled dichiarato in alto:

function foo() { 
    var i = 0, j; 
    while (i++ < 10) { 
    j = i * i; 
    } 
} 

mi chiedo se non v'è alcuna differenza reale tra questi due metodi. In altre parole, la parola chiave var non fa altro che stabilire un ambito?

motivi che ho sentito a preferire il secondo metodo:

  1. Il primo metodo dà l'aspetto del campo di applicazione di blocco quando è in realtà la funzione scope.
  2. Le dichiarazioni variabili vengono issate su la parte superiore dell'ambito, quindi è qui che devono essere definite.

Ritengo che questi motivi siano buoni ma soprattutto stilistici. Ci sono altri motivi che hanno più a che fare con la funzionalità, l'allocazione della memoria, le prestazioni, ecc.?

+0

Dubito che i 4 byte per "var" rispetto ai due byte per "," non siano significativi. –

+0

@LeeMeador Non sarei d'accordo.È solo 4 byte se è UTF-8 o ASCII e combina diversi file JavaScript di grandi dimensioni in un progetto di grandi dimensioni e stai parlando di una buona quantità di risparmio. – Lloyd

+0

@Lloyd Irrilevante. Compressione HTTP e minimizzatori intelligenti (ad esempio Clojure Compiler). –

risposta

3

Non ci saranno differenze durante il tempo di esecuzione . Potrebbe esserci una differenza impercettibilmente piccola nell'interpretazione/tempo di compilazione, ma ovviamente dipenderà dall'implementazione. Potrebbe anche esserci qualche byte diverso nella dimensione del file, che potrebbe anche influenzare il tempo di download. Non penso che nessuno di questi valga la pena di essere disturbato.

Come già sapete, qualsiasi dichiarazione di variabile verrà issata nella parte superiore della funzione. La cosa importante da notare è che si verifica durante il processo di interpretazione/compilazione, non durante l'esecuzione.

Prima di eseguire una funzione, è necessario analizzare la funzione . Dopo che ciascuna funzione è stata analizzata, entrambe avranno le dichiarazioni delle variabili spostate in alto, il che significa che saranno identiche e non ci saranno costi di esecuzione sostenuti.

Per lo stesso motivo, non ci sono differenze di costo di memoria. Dopo l'analisi, ci sarà nessuna differenza.


Dato che non si sta parlando di stile, non ti sto dicendo quale penso sia meglio. Ma dirò che l'unico motivo per cui preferisci uno rispetto all'altro è lo stile.

+2

"Durante l'analisi di una funzione" potrebbe essere più preciso. Non vi è alcuna garanzia di compilazione e il 'var' issamento può - e deve - essere esattamente riscritto * prima * una funzione viene eseguita. –

+0

@ pst Hai ragione, stavo usando il termine "compilazione" piuttosto liberamente. –

+0

@ pst hai una fonte per questa affermazione? "Il sollevamento di' var' può - e deve - essere esattamente riscritto 'prima' che viene eseguita una funzione"? –

0

L'esempio funzionerà esattamente allo stesso modo. Tuttavia, potrebbe essere ancora più oscuro del tuo esempio per usare 'var' in un blocco. Supponiamo, ad esempio, di aggiornare una variabile esterna all'ambito (non utilizzando "var") in modo condizionale, o di utilizzare invece una "var" locale.Anche se questa condizione è falsa, 'j' diventa locale. Risulta non essere così banale come sembra farlo.

var j = 1; 
function foo() { 
    j = 2; 
    if (false) { 
     var j = 3; // makes `j = 2` local simply for being in the same function 
    } 
    console.log(j); 
} 
foo(); // outputs 2 
console.log(j); // outputs 1 

Questo è un caso complicato che potrebbe non funzionare come previsto semplicemente guardando il codice.

ci sono aspetti negativi di dichiarare ogni 'var' in alto, solo fino-lati.

+0

Questo è indicato come "sollevamento", a proposito. Tutte le dichiarazioni variabili sono issate in cima alla funzione, quindi si comporta come se scrivessi tutto in alto comunque. –

+2

@ColinDeClue, L'OP sa che questo sta sollevando, e non si comporta come "hai scritto tutto in cima comunque", si comporta come 'var j;' è stato scritto nella parte superiore indipendentemente da dove sia var j ', nella funzione. Sollevare non imposta 'j' su 3, indipendentemente dal fatto che si trovi in ​​una condizione falsa, però. A causa della confusione e della bruttezza del sollevamento in generale, tutte le variabili dovrebbero essere dichiarate al vertice del suo scopo. –

+0

Scusa, sì, non volevo dire che si comporta come se tutto fosse scritto in alto, solo che si comporta come se tutte le dichiarazioni fossero in cima. Inoltre, sì, ci sono certamente degli svantaggi nel dichiarare ogni 'var' in alto. Se ti capita di avere una funzione particolarmente lunga (cosa che non dovresti), diminuisce la leggibilità spostando ulteriormente la dichiarazione dall'utilizzo. –

0

Il secondo modo in cui salva i 4 caratteri nel file javascript - ma in termini di velocità di generazione di codice o di effettiva esecuzione non credo ci sia alcuna differenza a tutti.

3

Stile

soggettivo. Preferisco l'approccio che mantiene close al sito di utilizzo, ma tengo sempre a mente le regole di scoping. Ho anche evito la combinazione di molteplici dichiarazioni in un unico var e preferiscono più var dichiarazioni.

allocazioni di memoria

Le variabili non sono oggetti: non applicabile. A causa delle regole di sollevamento, la variabile "slot" ha la stessa durata in tutti i casi.

prestazioni

No. Ci dovrebbe essere alcuna differenza in termini di prestazioni. Mentre un'implementazione potrebbe tecnicamente davvero rovinare tutto - non lo fanno.

L'unico modo per rispondere a questa (oltre a guardare ogni implementazione in minuzie) è quello di use a benchmark.

Risultato: le differenze di rumore sul browser moderni

+2

Ho anche creato un jsperf per questo: http://jsperf.com/inner-versus-outer-var-declarations che mostra una differenza trascurabile. –

+0

@TravisJ: Bello :) Penso che in un'immagine più grande prendere l'abitudine di non dichiarare le tue variabili nella parte superiore dello scope avrà un rischio più elevato di portare a errori difficili da debug rispetto al contrario. – Nope

+1

@ FrançoisWahl Non sono d'accordo - ma lascio tale nel regno di "soggettivo" :) –

3

In JavaScript - The Good Parts Douglas Crockford suggerisce che utilizzando il secondo metodo e dichiarando le variabili nella parte superiore del loro campo di applicazione sarà più facile evitare errori di portata.

Questi sono spesso causati da for loop, e può essere estremamente difficile da rintracciare, come verranno generati errori. Per esempio;

function() { 
    for (var i = 0; i < 10; i++) { 
    // do something 10 times 
    for (var i = 0; i < 5; i++) { 
     // do something 5 times 
    } 
    } 
} 

Quando le variabili sono issate si finisce con una sola i. E così il secondo ciclo sovrascrive il valore, dandoci un ciclo infinito.

è anche possibile ottenere alcuni risultati bizzarri quando si tratta con la funzione di sollevamento. Prendi questo esempio:

(function() { 
    var condition = true; 
    if(condition) { 
    function f() { console.log('A'); }; 
    } else { 
    function f() { console.log('B'); }; 
    } 
    f(); // will print 'B' 
})(); 

Questo perché i corpi delle funzioni vengono sollevati e la seconda funzione sovrascrive la prima.

Perché la ricerca di errori di questo tipo è difficile e indipendentemente da qualsiasi problema di prestazioni (raramente mi interessa un paio di microsecondi), dichiaro sempre le mie variabili in cima all'ambito.

+0

Sì, ho letto "JavaScript - Le parti buone". Non stavo cercando una risposta sulle migliori pratiche però. Volevo sapere cosa stava succedendo sotto il cofano. –

+1

Devo aver perso l'ultima frase :) Tuttavia, penso che questo sia molto più importante. – Jivings

+0

* non esiste il sollevamento delle funzioni *. L'ultimo esempio presentato è * JavaScript non valido * e sia IE che FireFox (e probabilmente Chrome) lo considerano errato o "bacato", ma in modi diversi. L'unico modo corretto per gestirlo è di generare un errore di sintassi in quanto tutte le altre alternative violano le specifiche. Le dichiarazioni di funzione possono apparire solo come una dichiarazione di livello superiore in un corpo di funzione o in un programma. –

Problemi correlati