2010-10-19 7 views
5

Wenn eine Variable könnte in einer Funktion definiert werden, auch wenn kein Wert zugewiesen zu definieren, ist es eine lokale VariableKeine Notwendigkeit, eine Variable zweimal

so, TestB() Programmierung besser wird ?

var test = 'SNAP!' 
function testA(boolean) { 
    if (boolean) var test = 'OK'; 
    else var test = null; 
    alert(test); 
} 
function testB(boolean) { 
    if (boolean) var test = 'OK'; 
    alert(test); 
} 
testA(true); // 'OK' 
testB(true); // 'OK' 
testA(false); // null 
testB(false); // undefined, no error 

In meinem speziellen globalen Wert Fall-Test ('SNAP!') Ist weder noch erforderlich erwartet.

+0

Benchmark es, http: // jsperf. com/undefined-Variablen –

Antwort

6

Sie können Variablen nicht bedingt deklarieren.

Warum?

Die Variable Instanziierung Prozess vor die eigentlichen Code-Ausführung, die zum Zeitpunkt tritt die Funktion ausgeführt wird, werden diese Variablen bereits auf dem lokalen Bereich gebunden werden, zum Beispiel:

function foo() { 
    if (false) { 
    var test = 'foo'; // never executed 
    } 
    return test; 
} 
foo(); // undefined 

Wenn die Funktion ist Auszuführende Identifikatoren formaler Parameter, Bezeichner aus Variablendeklarationen und Bezeichner aus Funktionsdeklarationen innerhalb des Funktionskörpers sind an die lokale Variablenumgebung gebunden.

Variablen werden mit initialisiert.

Auch Identifikatoren im lokalen Bereich Schatten die andere mit dem gleichen Namen, höher im Rahmen Kette, zum Beispiel:

var test = 'global'; 
function bar() { 
    alert(test); // undefined, not "global", the local variable already declared 
    var test = 'xxx'; 
} 
bar(); 

Wenn die test Variable nicht überall deklariert wurden, wird ein ReferenceError sein geworfen:

function foo() { 
    return test; 
} 

try { 
    foo(); // ReferenceError!! 
} catch (e) { 
    alert(e); 
} 

das über einer der Gründe ist, warum zum Beispiel empfiehlt JSLint nur one var statement an der Spitze der Funktionen, weil zum Beispiel t er erste Schnipsel, wird dies tatsächlich ähneln, wenn sie ausgeführt:

function foo() { 
    var test; // var statement was "hoisted" 
    if (false) { 
    test = 'foo'; // never executed 
    } 
    return test; 
} 
foo(); // undefined 

Ein weiterer Grund ist, weil Blöcke keinen neuen lexikalischen Gültigkeitsbereich einzuführen, funktioniert nur tun es, so eine var Aussage innerhalb eines Hinschauen könnte man denken, dass Die Lebensdauer der Variablen ist nur auf diesen Block beschränkt, aber das ist nicht der Fall.

Verschachtelte Funktionsdeklarationen ein ähnliches Verhalten von hoisting haben, werden sie vor die Ausführung von Code deklariert werden, aber sie sind auch in diesem Moment initialisiert:

function foo() { 
    return typeof bar; 
    // unreachable code: 
    function bar() { 
    //.. 
    } 
} 
foo(); // "function" 
+1

Nur um dies zu erläutern ... Ich glaube, was CMS (und JSLint) mit "Eine Var-Anweisung pro Funktion" meint, egal wie viele Variablen deklariert sind, deklariere sie alle oben in einer Zeile mit Kommas zum Trennen Sie lauten: 'var test = 'test', value = 'value', run = 'rum';' – treeface

+0

@treeface, yep, der zweite Grund, warum JSLint dies empfiehlt, sind 'Block'-Anweisungen (wie die' { } Blöcke, die nach Iterationsanweisungen verwendet werden, 'if' Anweisung usw., führen keinen neuen Bereich ein, nur Funktionen führen eine neue lexikalische Umgebung ein, in der Variablen deklariert werden können. Eine "var" -Anweisung am Anfang der Funktion kann also Verwirrung vermeiden. – CMS

+0

Danke. Ich fügte der Frage etwas hinzu, um klarzustellen, dass ich nicht erwartete, Variablen bedingt zu deklarieren, das hatte ich bereits gelernt. Meine Frage war mehr, was Sie über JSLint gesagt haben (wird das in der Zwischenzeit überprüfen), ist die Leistung ein Faktor für diese Empfehlung? –

4

Wenn die Variable muss nicht durch andere Funktionen, halten Sie die Variable in einer Funktion mit var foo; manipuliert werden.

Andernfalls, wenn es muss zugegriffen werden und lesen in mehreren Bereichen, halten Sie es draußen. Aber denken Sie daran, dass wenn Sie es draußen halten, es global wird. Das heißt, es sei denn, Sie alles in einer selbst ausgeführte Funktion setzen, das der beste Weg ist:

(function() { 
    var president='bush'; 

    function blah() { 
    president='reagan'; 
    } 

    function meh() { 
    president= 'carter'; 
    } 

    document.getElementById('reagan').onclick=blah; 
    document.getElementById('carter').onclick=meh; 


})(); 

alert(president) // undefined 

Die oben ist perfekt für eine Variable, die durch Funktionen zugegriffen definiert innerhalb dieses Bereichs. Da es zwei Elemente gibt, auf die ich klicke, um den Präsidenten festzulegen, ist es sinnvoll, sie außerhalb beider Funktionen zu definieren, da sie dieselbe Variable festlegen.

Wenn Sie also nicht mit mehreren Funktionen arbeiten, die genau die gleiche Variable ändern, behalten Sie sie lokal für die Funktion.

+0

Ich verstehe Ihren Punkt, ich entdeckte dies beim Debuggen in einer Situation, wo ich den globalen Wert des Tests ("SNAP!") verwenden wollte. Aber in diesem Fall möchte ich, dass es null und kein globaler Wert ist. Ich habe mich nur gefragt, ob das als eine gute Übung angesehen wurde. Vielen Dank. –

+0

Warnung (Präsident) würde einen Fehler –

+0

@Juan Mendes werfen - richtig. Das ist zur Demonstration. –

2

Ist testB besser programmierbar? Nein, weil es ein unerwartetes Ergebnis von "undefined" ergibt (zumindest war ich davon überrascht) und es ist schwer zu lesen.

Im Allgemeinen sollten Variablen auf den Bereich beschränkt sein, der sie erfordert. Wenn also die Variable "test" außerhalb der Funktion nicht benötigt wird, sollte sie als lokal deklariert werden. Um Verwirrung zu vermeiden, erklären Ihre Variable, bevor es mit:

function testC(boolean) { 
    var test; 
    if (boolean) { 
     test = "OK"; 
    } 
    else { 
     test = null; 
    } 
    alert(test); 
} 

Es sei denn, Sie wirklich die globale Reichweite Version von „test“ zu ändern, wobei in diesem Fall nicht das Schlüsselwort var in der Funktion verwenden.

Wenn Sie jemals den gleichen Namen für eine lokale Variable und eine globale Variable finden, können Sie eine davon umbenennen.

+0

Nun, jetzt, wo ich es erwarte und will (ich brauche nicht 'SNAP!'), Warum ist es nicht OK ? Performance? Oder nur Lesbarkeit? –

+1

Nur Lesbarkeit und Wartbarkeit (die fast Synonyme sind). Wenn Sie eine globale Variable haben, die Sie nicht brauchen, werden Sie sie eines Tages versehentlich irgendwo anders überschreiben und einen Tag lang herausfinden, warum alles kaputt gegangen ist. –

+0

Oder besser definiert, Globals fügen enge Kopplung zwischen Ihrem Modul und der Umgebung hinzu. Wenn Sie Ihr Modul erneut verwenden müssen, müssen Sie diese Globals verfolgen und sie in einer separaten Umgebung replizieren. Wenn Sie eine Variable zwischen ein paar Funktionen teilen müssen, ist die Selbstaufruf-Funktion ein großartiges Muster –

Verwandte Themen