2015-06-14 4 views
5

Ich habe mir eine Weile Sorgen gemacht und ich kann nicht erkennen, was wirklich passiert. Erklärung in Code-Kommentaren. Es gibt 2 Versionen einer Anwendung, eine davon wirft seltsame Ergebnisse und die zweite die erwartete Arbeit.Sehr seltsames Verhalten bei der Verwendung von "var" Schlüsselwort in einer Ajax Anfrage

var id = "test1"; 

$.post("http://fiddle.jshell.net/echo/json/", {"data": "data"}, function(a) { 
    alert(id); // will throw undefined 

    var id = "test2"; 
    alert(id); // will throw "test2" as expected 
}); 

$.post("http://fiddle.jshell.net/echo/json/", {"data": "data"}, function(a) { 
    alert(id); // will throw "test1" as expected 

    id = "test2"; 
    alert(id); // will throw "test2" as expected 
}); 

Ich bin mir nicht sicher, ob es etwas mit Ajax-Aufruf zu tun hat, oder eine anonyme Funktion, aber das ist nur die Art, wie ich dies so entdeckte ich es dort besser zu halten. Könnte jemand erklären, was ich vermisse? Warum verhält es sich anders, wenn ich das Schlüsselwort var weglasse? Sie können alles ausprobieren here on jsFiddle

+0

ich nicht das Gefühl, das ist eine exakte Kopie, wie es Frage der Zeit gefragt ist habe ich nicht Idee des Hochziehens. Dies ist eher eine Frage, die fragt "was ist das", nicht "wie es sich verhält". Voting wieder zu öffnen –

Antwort

8

Cool, Sie haben entdeckt hoisting. MDN erklärt es wie jemand so gut:

Da Variablendeklarationen (und Erklärungen im Allgemeinen) sind verarbeitet, bevor ein Code ausgeführt wird, eine Variable überall im Code deklarieren gleichwertig ist 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 Deklaration der Variablen an den Anfang des Funktions- oder globalen Codes verschoben wird.

Codebeispiel von MDN unten stehenden Link:

bla = 2 
var bla; 
// ... 

// is implicitly understood as: 

var bla; 
bla = 2; 

Sie können sehen, wie dies in der "seltsame Verhalten" führen wird:

alert(testId); 
var testId = 2; 

entspricht:

var testId; 
alert(testId); 
testId = 2; 

Was bringt mich zu dem letzten Stück Wissen, das ich vermitteln kann, immer Ihre Variablen, die am Anfang der Codeblöcke deklarieren so dass diese „seltsame Verhalten“ in Ihre Programme codiert (und Sie nie wieder abwirft):

function someFunction() { 
    var 
    firstVar, 
    secondVar, 
    thirdVar; 

    //rest of your code statements here 
} 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting

+1

wow, ich habe gerade wirklich interessante Sache gelernt! Ich wette, ich werde dies im Hinterkopf behalten, danke –

+0

Nur eine andere Frage, bedeutet dies, dass jede Zeile, die nicht einmal ausgeführt wird (innerhalb einer Funktion) den gesamten Code brechen kann? Basierend auf Ihrer letzten Bearbeitung, lässt es mich denken, dass es nur "hisst", bevor die Funktion ausgeführt wird. Habe ich recht? –

+0

@Martin. absolut.'var zehn = 10; (Function()() {if (false) {var zehn = false;;} alert (zehn)/* Warnungen nicht definiert, auf den ersten Blick erwarten würde Sie es 10 */aufmerksam zu machen}); ' – Adam

3

Seine Hebe genannt. var id wird an den Anfang der Funktion verschoben.

+0

Ohne den Wert zu füllen? –

+1

@Martin - richtig. Er deklariert die Variable vor allen anderen Codeanweisungen, so dass sie nicht undefiniert ist, und weist dann den Wert der ursprünglichen Codezeile zu. – Adam

4

Wie die anderen sagten, ist es hissen. Aber nur, damit Sie eine bessere Sicht auf haben kann, was geschieht, der erste Code ist tatsächlich wie folgt ausgeführt:

var id = "test1"; 

$.post("http://fiddle.jshell.net/echo/json/", {"data": "data"}, function(a) { 
    // this is because of hoisting 
    var id = undefined; 
    alert(id); // will throw undefined 

    id = "test2"; 
    alert(id); // will throw "test2" as expected 
}); 
+1

Nun, ich glaube, ich bin nicht ganz sicher, warum das passiert ist. Es geht durch den Code, initialisiert die Variable „id“ ohne (somit clearing Wert aus der ersten Zeile) in einem beliebigen Wert zu Füllen und füllt seinen Wert auf „Test2“ nach dem ersten Alarm,? –

+0

@Martin. Genau wie du gesagt hast. –

Verwandte Themen