849 Stimmen

Was ist lexikalischer Geltungsbereich?

Was ist eine kurze Einführung in das lexikalische Scoping?

109 Stimmen

In Podcast 58 ermutigt Joel zu Fragen wie diesen, da er möchte, dass SO DER Ort für Antworten wird, auch wenn sie bereits an anderer Stelle beantwortet wurden. Dies ist eine berechtigte Frage, auch wenn man sie etwas höflicher formulieren könnte.

0 Stimmen

Und dann speziell de.wikipedia.org/wiki/Scope_(Programmierung) die ein schönes (Pascal/Delphi) Beispiel für verschachtelte Bereiche in verschachtelten Prozeduren enthält.

18 Stimmen

Es ist möglich, dass der Fragesteller nicht fließend Englisch spricht (oder sprach), als er diese Frage schrieb.

15voto

Stan Punkte 139

Lexikalisches Scoping: Variablen, die außerhalb einer Funktion deklariert werden, sind globale Variablen, die überall in einem JavaScript-Programm sichtbar sind. Variablen, die innerhalb einer Funktion deklariert sind, haben Funktionsumfang und sind nur für den Code sichtbar, der innerhalb dieser Funktion erscheint.

13voto

Robert Rocha Punkte 9410

IBM definiert sie als:

Der Teil eines Programms oder einer Segmenteinheit, in dem eine Deklaration gilt. Ein in einer Routine deklarierter Bezeichner ist innerhalb dieser Routine und in allen verschachtelten Routinen bekannt. Deklariert eine verschachtelte Routine ein Element mit demselben Namen deklariert, ist das äußere Element in der verschachtelten Routine.

Beispiel 1:

function x() {
    /*
    Variable 'a' is only available to function 'x' and function 'y'.
    In other words the area defined by 'x' is the lexical scope of
    variable 'a'
    */
    var a = "I am a";

    function y() {
        console.log( a )
    }
    y();

}
// outputs 'I am a'
x();

Beispiel 2:

function x() {

    var a = "I am a";

    function y() {
         /*
         If a nested routine declares an item with the same name,
         the outer item is not available in the nested routine.
         */
        var a = 'I am inner a';
        console.log( a )
    }
    y();

}
// outputs 'I am inner a'
x();

7voto

Sean Punkte 807

Ich hoffe, das ist hilfreich. Hier ist mein Versuch einer etwas abstrakteren Definition:

Lexikalischer Anwendungsbereich : Der Zugriff oder die Reichweite, die etwas (z.B. eine Funktion oder Variable) zu anderen Elementen im Programm hat, bestimmt durch seine Position im Quellcode.

Übrigens baut meine Logik hier einfach auf den Definitionen von auf:

Lexikalisch : bezieht sich auf die Wörter oder das Vokabular einer Sprache (speziell das Wort, getrennt von seiner Grammatik oder seinem Aufbau) {in unserem Fall - eine Programmiersprache}.

Umfang (Substantiv): der Bereich der Operation {in unserem Fall ist der Bereich: das, worauf zugegriffen werden kann}.

Hinweis: Das Original von 1960 Definition von Lexical Scope aus der ALGOL 60-Spezifikation ist viel prägnanter als mein obiger Versuch:

Lexikalische Reichweite: der Teil des Quellcodes, in dem eine Bindung eines Namens mit einer Entität gilt. fuente

6voto

Kenneth Stoddard Punkte 1269

Der lexikalische Bereich bezieht sich auf das Lexikon der Bezeichner (z. B. Variablen, Funktionen usw.), die von der aktuellen Position im Ausführungsstapel aus sichtbar sind.

- global execution context
    - foo
    - bar
    - function1 execution context
        - foo2
        - bar2
        - function2 execution context
            - foo3
            - bar3

foo y bar sind immer im Lexikon der verfügbaren Identifikatoren enthalten, da sie global sind.

Wenn function1 ausgeführt wird, hat es Zugriff auf ein Lexikon von foo2 , bar2 , foo y bar .

Wenn function2 ausgeführt wird, hat es Zugriff auf ein Lexikon von foo3 , bar3 , foo2 , bar2 , foo y bar .

Der Grund dafür, dass globale und/oder äußere Funktionen keinen Zugriff auf die Bezeichner einer inneren Funktion haben, liegt darin, dass die Ausführung dieser Funktion noch nicht stattgefunden hat und daher noch keine ihrer Bezeichner dem Speicher zugewiesen wurden. Darüber hinaus wird der innere Kontext nach seiner Ausführung vom Ausführungsstapel entfernt, was bedeutet, dass alle seine Bezeichner in den Müll geworfen wurden und nicht mehr verfügbar sind.

Aus diesem Grund kann ein verschachtelter Ausführungskontext IMMER auf den Ausführungskontext seines Vorgängers zugreifen und hat somit Zugang zu einem größeren Lexikon von Identifikatoren.

Siehe:

Besonderen Dank an @robr3rd um die obige Definition zu vereinfachen.

4voto

Manngo Punkte 10358

Eine uralte Frage, aber hier ist meine Meinung dazu.

Lexikalisch (statischer) Bereich bezieht sich auf den Bereich einer Variablen in der Quellcode .

In einer Sprache wie JavaScript, wo Funktionen herumgereicht und an verschiedene Objekte angehängt und wieder angehängt werden können, könnte man meinen, dass der Geltungsbereich davon abhängt, wer die Funktion gerade aufruft, aber das tut er nicht. Das Ändern des Geltungsbereichs auf diese Weise wäre dynamischer Geltungsbereich, und JavaScript tut das nicht, außer vielleicht mit dem this Objektreferenz.

Zur Veranschaulichung des Sachverhalts:

var a='apple';

function doit() {
    var a='aardvark';
    return function() {
        alert(a);
    }
}

var test=doit();
test();

In diesem Beispiel wird die Variable a ist global definiert, wird aber in der doit() Funktion. Diese Funktion gibt eine andere Funktion zurück, die sich, wie Sie sehen, auf die a Variable außerhalb ihres eigenen Bereichs.

Wenn Sie dies ausführen, werden Sie feststellen, dass der verwendete Wert aardvark , nicht apple die zwar in den Anwendungsbereich der test() Funktion, nicht im lexikalischen Bereich der ursprünglichen Funktion liegt. Das heißt, der verwendete Bereich ist der Bereich, wie er im Quellcode erscheint, und nicht der Bereich, in dem die Funktion tatsächlich verwendet wird.

Diese Tatsache kann unangenehme Folgen haben. Sie könnten zum Beispiel beschließen, dass es einfacher ist, Ihre Funktionen getrennt zu organisieren und sie dann zu gegebener Zeit zu verwenden, z. B. in einem Ereignis-Handler:

var a='apple',b='banana';

function init() {
  var a='aardvark',b='bandicoot';
  document.querySelector('button#a').onclick=function(event) {
    alert(a);
  }
  document.querySelector('button#b').onclick=doB;
}

function doB(event) {
  alert(b);
}

init();

<button id="a">A</button>
<button id="b">B</button>

In diesem Codebeispiel wird eines von beiden durchgeführt. Sie können sehen, dass aufgrund des lexikalischen Scopings die Schaltfläche A verwendet die innere Variable, während die Schaltfläche B nicht. Es kann sein, dass Sie mehr Funktionen verschachteln, als Ihnen lieb ist.

Übrigens werden Sie in beiden Beispielen auch feststellen, dass die inneren lexikalisch skalierten Variablen bestehen bleiben, auch wenn die enthaltende Funktion ihren Lauf genommen hat. Dies wird als Verschluss und bezieht sich auf den Zugriff einer verschachtelten Funktion auf äußere Variablen, auch wenn die äußere Funktion beendet ist. JavaScript muss intelligent genug sein, um festzustellen, ob diese Variablen nicht mehr benötigt werden, und wenn nicht, kann es sie zu Müll sammeln.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X