2016-06-20 10 views
1

Nach diesem Code:Warum hat die innere Funktion in diesem Fall keinen Zugriff auf die äußere Variable?

class Thing { 
    constructor() { 
     this.bar = (typeof foo !== "undefined"? foo : null); // (3) 
    } 

    static create() { 
     var foo = arguments[0]; 
     return new Thing(); 
    } 
} 

die neuen Thing könnte auf zwei Arten erstellt werden: entweder direkt mit new Thing oder mit Thing.create().

Wenn es auf die zweite Art erstellt wird, wird eine neue Variable string deklariert. Theoretisch sollte es innerhalb des gesamten Geltungsbereichs bis zur return-Anweisung sichtbar sein, aber in der Thing.constructor() (die innerhalb Thing.create() aufgerufen wird) ist die string nicht zu sehen. Und Thing.prototype.bar ist immer null.

Warum ist es so?


Hier ist aus der inner() Funktion gesehen:

(function outer() { 
    var foo = 5; 

    (function inner() { 
     alert(foo); 
    })() 
})(); 

Antwort

2

Theoretisch sollte es innerhalb der ganzen Umfang bis auf die return Anweisung

Nr sichtbar sein

Es ist für keine Funktion sichtbar, die innerhalb desselben Bereichs aufgerufen wird. Ich werde für jede Funktion innerhalb desselben Bereichs sichtbar sein.

Und in diesem Beispiel ist die constructor() Funktion in einem höheren Bereich als die string Variable.

Dies funktionieren würde:

class Thing { 
    constructor(prop) { 
     this.prop = prop; 
    } 

    static create() { 
     return new Thing(arguments[0]); 
    } 
} 

, die, nebenbei gesagt, nichts anderes als syntaktischer Zucker ist für:

function Thing(prop) { 
    this.prop = prop; 
} 
Thing.create = function() { 
    return new Thing(arguments[0]); 
}; 
+1

Javascript außerhalb von 'Verwendung strict' Modus aufgerufen einen Bereich Suche durchführen [var Hubwerk] (https: //developer.mozilla.org/de-DE/docs/Web/JavaScript/Referenz/Statements/var) - vielleicht OP ist verwirrt, aber hoffentlich lesen über Schließungen und hissen wird erklären, warum die 'var foo' nicht innerhalb des Konstruktors in dem Aufruf an ist 'create()' – kirinthos

+0

hoppla, es tut mir leid, dass du völlig richtig bist, ich dachte daran, eine Variable zu benutzen, ohne sie zu deklarieren - aber ich habe nichts über das Ändern der Funktionen gesagt, nur dass die Schließung in den Funktionen anders ist Dies erklärt, warum foo im Konstruktor nicht zugänglich ist. – kirinthos

+0

Nebenbei, im zweiten Beispiel sollte 'create' wahrscheinlich an' function Thing' selbst angehängt werden, anstelle des Prototyps von 'Thing'. Ich glaube, so würden die meisten statische Funktionen für möglich halten. – noppa

2

Was Sie (Funktionen erben Variablenbindungen von den Funktionen passieren erwarten, dass genannt) ist als dynamischer variabler Bereich bekannt. Auf der anderen Seite hat Javascript statische (auch bekannt als lexikalischen) Variablenbereich, was bedeutet, dass diese Variablen Bindungen basieren auf rein was Funktionen ineinander im Quellcode verschachtelt sind. Dies ist eine gute Sache, weil es bedeutet, dass Sie nicht darüber nachdenken müssen, wie Ihre Funktionen aufgerufen werden, um herauszufinden, was ihre Variablen bedeuten. Sie müssen nur schauen, wie die Funktionen geschrieben sind.

Weitere Informationen über den Unterschied zwischen lexikalischen und dynamischen Scoping, die Wikipedia-Artikel scheint ein guter Ort, um zu starten: https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping

Verwandte Themen