2015-04-16 8 views
28

Ich verstehe nicht ganz, warum die folgenden Anzeigen gegen Ende "gehisst".'Hoisted' JavaScript Variablen

var x = 'set'; 
var y = function() 
{ 
    // WHAT YOU DON'T SEE -> var x; 
    // is effectively "hoisted" to this line! 

    if (!x) 
    { 
     // You might expect the variable to be populated at this point...it is not 
     // though, so this block executes 
     var x = 'hoisted'; 
    } 

    alert(x); 
} 

//... and this call causes an alert to display "hoisted" 
y(); 

Alle Zeiger würden geschätzt werden.

+0

es ist äquivalent zu 'var y = function() {var x; ... ', wodurch' x' lokal zur Funktion und nicht zugewiesen bleibt. wenn blocks nicht "stoppen" "var" vom Hochziehen – dandavis

+0

Ja, "var x" hebt an den Anfang des Bereichs, dies ist normales Verhalten der Variablendeklaration in JS. – dfsq

+2

@ Qantas94Heavy: Dieses könnte tatsächlich ein gutes kanonisches Duplikat für variables Heben werden, afaik haben wir momentan nicht. Nur für [Funktion hissen] (http://stackoverflow.com/q/7506844/1048572) ... – Bergi

Antwort

33

MDN Docs on var hoisting Zitiert,

Da Variablendeklarationen (und Erklärungen im allgemeinen) verarbeitet werden, bevor jeder Code ausgeführt wird, wird eine Variable irgendwo im Code erklärt entspricht es an der Spitze zu erklären. Dies bedeutet auch, dass eine Variable verwendet werden kann, bevor sie deklariert wird. Dieses Verhalten wird als "Hochziehen" bezeichnet, da die Variablendeklaration scheinbar an den Anfang der Funktion oder des globalen Codes verschoben wird.

Also, in Ihrem Fall, weiß, JavaScript, dass eine lokale Variable (nicht außen erklärte eins)x irgendwo in der Funktion definiert ist, aber es weiß nicht, den tatsächlichen Wert, bis die Ausführung einen erreicht Zuweisungsanweisung, die x zuweist. (Deklarationen werden während der Kompilierzeit verarbeitet und Aufgaben werden in der Ausführungszeit ausgeführt) Bis die Zuweisung erfolgt ist, wird der Standardwert undefined verwendet. Da undefined is falsy die Bedingung

if (!x) { 

erfüllt ist und die Zuordnung Anweisung ausgeführt wird. Deshalb erhalten Sie hoisted in der Alarmbox.


Angenommen, Sie haben in der Funktion nicht x erklärt,

var x; 

var y = function() { 
    if (!x) { 
     x = 'hoisted'; 
    } 
    alert(x); 
} 

y(); 
alert(x); 

Da hier x ist nicht überall in der Funktion zur Laufzeit erklärt, JavaScript für x in den höheren Bereichen suchen. In diesem Fall findet es es direkt außerhalb der Funktion. Also, dass x wird verwendet. Da Sie hoisted zu x zugewiesen haben, wird der innere alert auch hoisted sagen und nach dem Verlassen der Funktion, alert(x) alarmiert auch hoisted.

12

Variable Deklarationen heben an den Anfang des Bereichs. So Ihr Code entspricht dies:

var x = 'set'; 
var y = function() { 
    var x; 
    if (!x) { 
     x = 'hoisted'; 
    } 
    alert(x); 
} 

y(); 

Wenn y ausgeführt wird, var x Schatten äußeren Umfang x so innerhalb der y Funktion x ist undefined nach der ersten Zeile der Erklärung.

+0

Wie kann der Wert der globalen Variablen in Funktion erhalten werden? – mhkyazd

+1

@mhkyazd mit dem globalen Objekt. – zerkms

+2

@mhkyazd einfach nicht 'var x' irgendwo in der Funktion schreiben, wenn' x' von einem äußeren Bereich kommt, so dass es nicht überschrieben wird. – floribon

2

this answer erklären Sie sehr detailliert die verschiedenen Bereiche der Variablen. In Ihrem speziellen Fall können Sie den folgenden Verweis verwenden:

this.x; 

Zugriff auf die globale Variable x außerhalb der Funktion. Da Sie innerhalb der Funktion versuchen, auf eine undefinierte Variable zuzugreifen, verwenden Sie das Schlüsselwort this, um auf Variablen außerhalb der Funktion zu verweisen.

Und der Teil

if(!x) 

Es ist wahr, weil Sie testen: is false und x in diesem Punkt ist undefined weil nicht im Funktionsumfang existieren, und undefined ist eine der falschen Werte in JS betrachten , für weitere Informationen please take a look here.

+0

Beachten Sie, dass die Verwendung von 'this' nur in diesem speziellen Fall funktioniert, da' x' direkt aufgerufen wird - wenn es auf ein anderes Objekt gesetzt wird, verweist 'this' nicht mehr auf das globale Objekt. –

4

Haha das Problem ist, Sie erstellen die Variable x wieder.

var x = 'set'; 
var y = function(){ 

if (!x) 
{ 
    // just use the = sign to update the value of it. 
    x = 'hoisted'; 

}; 
alert(x); 
}; 

y();