2015-01-21 8 views
29

Ich habe über JavaScript gelesen Bereiche und Hoisting. Ich sah eine Probe wie unten, die einige Zweifel in mir aufkommen ließ. Also habe ich mich gefragt, wie es funktioniert.Wie der unten JavaScript Scope funktioniert

var a = 1; 
function b() { 
    a = 10; 
    return; 
    function a() {} 
} 
b(); 
alert(a); 

wird der Code alarmieren! Aber wenn wir die "Funktion a() {}" Teil beseitigen, alarmiert der Code 10.

Also, wie funktioniert es! Was macht die "Funktion a() {}" hier und wie wirkt sie sich auf die Bereiche aus?

Ich kann auch nicht die Bedeutung eines leeren "Rückkehr" verstehen; in diesem Code.

Also, wie funktioniert dieser Code unter Verwendung der JavaScript Scopes?

+4

über "Hebe" Lesen auf. – elclanrs

+8

Dies wird "hissen" genannt und hier ist ein Artikel, der es erklärt und den genauen Code verwendet! http://www.acquatelygood.com/JavaScript-Scoping-and-Hoisting.html – Dom

+0

Ja. Ich habe über das Heben gelesen, aber ich habe immer noch Zweifel. Basierend auf dem Hochladen werden Funktionsdeklarationen und Variablendeklarationen immer von dem JavaScript-Interpreter unsichtbar an den Anfang ihres enthaltenden Bereichs verschoben ("hochgezogen"). Also, ich kann immer noch nicht verstehen, wie es diesen Code beeinflusst. –

Antwort

33

Als Erstes verlässt eine "leere" return;-Anweisung einfach die Funktion an diesem Punkt und gibt zurück. Es entspricht return undefined;.

Der einfache Fall, wenn Sie den function a(){} Teil beseitigen ist, dass die b() Funktion der globale Variable ändert a10, so dann sein, wenn Sie den Wert a nach dem Ausführen der es 10 ist b() Funktion alarmieren. Ohne diese innere Funktion bedeuten alle Verweise auf a die globale Variable.

Aber mit der function a(){} Teil, wird diese Funktion innerhalbb() erklärt. Es ist lokal zu b(). Dann haben Sie zwei verschiedene a s: die globale Variable und die lokale Variable in b(). Unabhängig davon, wo innerhalb der enthaltenden Funktion eine andere Funktionsanweisung angezeigt wird, wird sie vom JS-Compiler so behandelt, als befände sie sich am Anfang der Funktion. Also auch wenn die function a(){} Linie am Ende der enthaltenden b() Funktion in der Tat ist das, was passiert, wenn der Code ausgeführt werden ist folgende:

var a = 1;    // declare a global variable a 
function b() { 
    function a() {}  // declare a local function a 
    a = 10;    // update local a to be 10 instead of a function 
    return; 
} 
b(); 
alert(a); // show value of global a, which is still 1 
+1

Eine andere Möglichkeit, Zeile 3 auszudrücken, die besser veranschaulichen könnte, was passiert, ist: 'var a = Funktion a() {};' (In diesem Fall ist das genau das Gleiche) – RikkusRukkus

+0

Gibt es einen expliziten Grund, warum JS Dolmetscher/Compiler machen das? – Traubenfuchs

+1

@Traubenfuchs - weil das die Sprachspezifikation sagt. (Der Compiler verschiebt die Deklarationen nicht wirklich, er kompiliert die Funktion einschließlich Deklarationen, und dann führt er die Funktion aus, aber konzeptionell hat die "hüpfende"/bewegte Idee das gleiche Ergebnis und die meisten Leute scheinen es einfacher zu visualisieren.) – nnnnnn

14

Neben nnnnnn's great answer habe ich versucht, die Situation zu vergegenwärtigen.

Mit function a(){}, verhält sich der Code wie folgt:

scope: window       scope: b 
     |         | 
     | var a = 1; //window.a = 1;  | 
     |         | 
     | function b() { -----------------> | 
     |         | function a(){} // b.a(){} (hoisted to top) 
     |         | a = 10;  // b.a = 10; 
     |         | return; 
     | } <------------------------------ | 
     |         | 
     | b();        | 
     | alert(a); // alert(window.a); | 

Wir können sehen, dass function a(){} an die Spitze der Funktion hochgezogen wird, weil er eine Erklärung enthält. Und wenn wir function a(){} entfernen, verhält sich der Code wie folgt:

scope: window       scope: b 
     |         | 
     | var a = 1; //window.a = 1;  | 
     |         | 
     | function b() { -----------------> | 
     |         | a = 10;  // window.a = 10; 
     |         | return; 
     | } <------------------------------ | 
     |         | 
     | b();        | 
     | alert(a); // alert(window.a); | 
+3

Schöne Diagramme dort. – nnnnnn

+0

Schönes Diagramm .. Völlig hilfreich –

6

Ihr Code ist funktional gleich zu diesem Code:

var a = 1; 
function b() { 
    var a = function() {} 
    a = 10; 
    return; 
} 
b(); 
alert(a); 

Mit der function NAME() { ... } Notation setzt effektiv die Funktion Erklärung zu Beginn der aktuelle Geltungsbereich als lokale Deklaration.

in der Tat, wenn Sie

var a = 1; 
var c= 2; 
function b() { 
    a() 
    a = 10; 
    return; 
    function a() { alert(c) } 
} 
b(); 
alert(a); 

ausführen Es wird ausgegeben:

2 
1 

persönlich immer explizit Zuweisungen ich nicht diese Art der Notation, ich.

jsfiddle

Verwandte Themen