Was ist lexikalischer Umfang?

Lesezeit: 10 Minuten

Was ist lexikalischer Umfang
Subba Rao

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

  • In Podcast 58 fördert Joel Fragen wie diese, da er möchte, dass SO DER Ort für Antworten wird, auch wenn sie an anderen Stellen beantwortet wurden. Das ist eine berechtigte Frage, auch wenn man sie etwas höflicher formulieren könnte.

    – Ralph M. Rickenbach

    26. Juni 2009 um 5:30 Uhr

  • @rahul Ich verstehe, dass es eine alte Frage ist. Aber ich bin mir sicher, dass SO sogar im Jahr 2009 von den Fragestellern erwartet wurde etwas grundlegender Aufwand hin zur Lösung. So wie es aussieht, wird es nicht angezeigt irgendein Anstrengung überhaupt. Vielleicht wurde es deshalb von vielen abgelehnt?

    – PP

    12. September 2013 um 12:05 Uhr

  • Es ist möglich, dass der Fragesteller beim Verfassen dieser Frage nicht fließend Englisch spricht (oder war).

    – Martin

    16. Januar 2014 um 19:24 Uhr

  • Die Frage ist höflich, er sagt einfach, was er will. Es steht Ihnen frei zu antworten. Übertriebene Höflichkeit ist hier nicht nötig.

    – Markus Siebeneicher

    24. April 2014 um 11:08 Uhr

  • Ich denke, Fragen wie diese sind großartig, weil sie Inhalte für SO erstellen. IMO, wen kümmert es, wenn die Frage keine Mühe macht … die Antworten werden großartigen Inhalt haben, und das ist es, was in diesem Message Board zählt.

    – Jwan622

    4. Oktober 2014 um 22:42 Uhr

Was ist lexikalischer Umfang
Khaled Alshaya

Ich verstehe sie anhand von Beispielen. 🙂

Zuerst, lexikalischer Umfang (auch genannt statischer Geltungsbereich), in C-ähnlicher Syntax:

void fun()
{
    int x = 5;

    void fun2()
    {
        printf("%d", x);
    }
}

Jede innere Ebene kann auf ihre äußeren Ebenen zugreifen.

Es gibt einen anderen Weg, genannt dynamischer Umfang verwendet von der ersten Implementierung von Lispelnwieder in einer C-ähnlichen Syntax:

void fun()
{
    printf("%d", x);
}

void dummy1()
{
    int x = 5;

    fun();
}

void dummy2()
{
    int x = 10;

    fun();
}

Hier fun kann entweder zugreifen x in dummy1 oder dummy2oder irgendein x in jeder Funktion, die aufruft fun mit x darin erklärt.

dummy1();

wird 5 drucken,

dummy2();

druckt 10.

Der erste heißt statisch, weil er zur Kompilierzeit abgeleitet werden kann, und der zweite heißt dynamisch, weil der äußere Gültigkeitsbereich dynamisch ist und vom Kettenaufruf der Funktionen abhängt.

Ich finde das statische Scoping einfacher für das Auge. Die meisten Sprachen gingen irgendwann so, sogar Lisp (kann beides, oder?). Dynamisches Scoping ist wie das Übergeben von Referenzen aller Variablen an die aufgerufene Funktion.

Als Beispiel dafür, warum der Compiler den äußeren dynamischen Bereich einer Funktion nicht ableiten kann, betrachten Sie unser letztes Beispiel. Wenn wir so etwas schreiben:

if(/* some condition */)
    dummy1();
else
    dummy2();

Die Aufrufkette hängt von einer Laufzeitbedingung ab. Wenn es wahr ist, sieht die Aufrufkette so aus:

dummy1 --> fun()

Wenn die Bedingung falsch ist:

dummy2 --> fun()

Der äußere Geltungsbereich von fun in beiden Fällen ist der Anrufer plus der Anrufer des Anrufers und so weiter.

Nur um zu erwähnen, dass die C-Sprache weder verschachtelte Funktionen noch dynamisches Scoping zulässt.

  • Ich möchte auch auf ein sehr sehr leicht verständliches Tutorial hinweisen, das ich gerade gefunden habe. Araks Beispiel ist nett, aber möglicherweise zu kurz für jemanden, der mehr Beispiele benötigt (eigentlich im Vergleich zu anderen Sprachen …). Schau mal. Es ist wichtig zu verstehen Dasda dieses Schlüsselwort uns dazu bringt, den lexikalischen Umfang zu verstehen. howtonode.org/what-is-this

    – CppLearner

    8. August 2011 um 6:13 Uhr


  • Dies ist eine gute Antwort. Aber die Frage ist mit markiert JavaScript. Daher denke ich, dass dies nicht als akzeptierte Antwort markiert werden sollte. Der lexikalische Umfang speziell in JS ist anders

    – Boyang

    1. Oktober 2016 um 10:29 Uhr

  • Extrem gute Antwort. Danke. @Boyang Ich bin anderer Meinung. Ich bin kein Lisp-Programmierer, fand das Lisp-Beispiel jedoch hilfreich, da es ein Beispiel für dynamisches Scoping ist, das Sie in JS nicht erhalten.

    – Dudewad

    10. Oktober 2016 um 20:36 Uhr

  • Anfangs dachte ich, das Beispiel sei gültiger C-Code und war verwirrt, ob es in C dynamisches Scoping gibt. Vielleicht könnte der Haftungsausschluss am Ende vor das Codebeispiel verschoben werden?

    – Yangshun Tay

    8. April 2017 um 7:28 Uhr

  • Dies ist immer noch eine sehr hilfreiche Antwort, aber ich denke, @Boyang ist richtig. Diese Antwort bezieht sich auf „Ebene“, was eher dem Blockbereich entspricht, den C hat. JavaScript hat standardmäßig keinen Geltungsbereich auf Blockebene, also innerhalb von a for Schleife ist das typische Problem. Der lexikalische Umfang für JavaScript liegt nur auf Funktionsebene, es sei denn, ES6 let oder const wird genutzt.

    – icc97

    19. April 2018 um 11:44 Uhr

1646635523 513 Was ist lexikalischer Umfang
Pierre Spring

Versuchen wir die kürzest mögliche Definition:

Lexikalischer Umfang definiert, wie Variablennamen in verschachtelten Funktionen aufgelöst werden: innere Funktionen enthalten den Gültigkeitsbereich von übergeordneten Funktionen, selbst wenn die übergeordnete Funktion zurückgegeben wurde.

Das ist alles, was dazu gehört!

  • Der letzte Teil: „auch wenn die Elternfunktion zurückgekehrt ist“ heißt Closure.

    – Juanma Menendez

    13. März 2019 um 15:18 Uhr

  • Lexical Scoping & Closure in nur einem Satz verstanden. Danke!!

    – Kerker

    1. Mai 2020 um 14:36 ​​Uhr

Was ist lexikalischer Umfang
kta

var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

Der obige Code gibt “Ich bin nur ein Einheimischer” zurück. Es wird nicht “Ich bin ein Global” zurückkommen. Weil die Funktion func() dort zählt, wo sie ursprünglich definiert wurde, was im Bereich der Funktion whatismyscope liegt.

Es wird nicht stören, was auch immer es aufgerufen wird (der globale Bereich / sogar aus einer anderen Funktion), deshalb wird der globale Bereichswert I am global nicht gedruckt.

Dies wird lexikalisches Scoping genannt, wobei “Funktionen werden unter Verwendung der Bereichskette ausgeführt, die bei ihrer Definition gültig war” – gemäß JavaScript Definition Guide.

Der lexikalische Umfang ist ein sehr, sehr mächtiges Konzept.

Hoffe das hilft..:)

  • Es ist eine sehr schöne Erklärung. Ich möchte noch etwas hinzufügen, wenn Sie die Funktion func() {return this.scope;} schreiben, dann wird “I am global” zurückgegeben. Verwenden Sie einfach dieses Schlüsselwort, und Ihr Bereich wird geändert

    – Rajesh Kumar Bhawsar

    11. September 2019 um 3:01 Uhr


Lexikalischer (auch bekannt als statischer) Geltungsbereich bezieht sich auf die Bestimmung des Geltungsbereichs einer Variablen ausschließlich auf der Grundlage ihrer Position innerhalb des textuellen Codekorpus. Eine Variable bezieht sich immer auf ihre Umgebung der obersten Ebene. Es ist gut, es zu verstehen Beziehung zum dynamischen Bereich.

1646635525 691 Was ist lexikalischer Umfang
Ralph M. Rickenbach

Scope definiert den Bereich, in dem Funktionen, Variablen und dergleichen verfügbar sind. Die Verfügbarkeit einer Variablen wird beispielsweise innerhalb ihres Kontexts definiert, sagen wir der Funktion, Datei oder dem Objekt, in dem sie definiert sind. Wir nennen diese normalerweise lokale Variablen.

Der lexikalische Teil bedeutet, dass Sie den Geltungsbereich aus dem Lesen des Quellcodes ableiten können.

Der lexikalische Geltungsbereich wird auch als statischer Geltungsbereich bezeichnet.

Der dynamische Geltungsbereich definiert globale Variablen, die nach ihrer Definition von überall aus aufgerufen oder referenziert werden können. Manchmal werden sie als globale Variablen bezeichnet, obwohl globale Variablen in den meisten Programmiersprachen lexikalischen Gültigkeitsbereich haben. Das heißt, es kann aus dem Lesen des Codes abgeleitet werden, dass die Variable in diesem Kontext verfügbar ist. Vielleicht muss man einer uses- oder include-Klausel folgen, um die Anweisung oder Definition zu finden, aber der Code/Compiler kennt die Variable an dieser Stelle.

Im Gegensatz dazu suchen Sie beim dynamischen Scoping zuerst in der lokalen Funktion, dann suchen Sie in der Funktion, die die lokale Funktion aufgerufen hat, dann suchen Sie in der Funktion, die diese Funktion aufgerufen hat, und so weiter, den Aufrufstapel hinauf. “Dynamisch” bezieht sich auf Änderungen, da der Aufrufstapel bei jedem Aufruf einer bestimmten Funktion unterschiedlich sein kann und die Funktion daher möglicherweise auf unterschiedliche Variablen trifft, je nachdem, von wo aus sie aufgerufen wird. (sehen Hier)

Ein interessantes Beispiel für dynamischen Bereich finden Sie unter Hier.

Näheres siehe Hier und Hier.

Einige Beispiele in Delphi/Object Pascal

Delphi hat einen lexikalischen Gültigkeitsbereich.

unit Main;
uses aUnit;  // makes available all variables in interface section of aUnit

interface

  var aGlobal: string; // global in the scope of all units that use Main;
  type 
    TmyClass = class
      strict private aPrivateVar: Integer; // only known by objects of this class type
                                    // lexical: within class definition, 
                                    // reserved word private   
      public aPublicVar: double;    // known to everyboday that has access to a 
                                    // object of this class type
    end;

implementation

  var aLocalGlobal: string; // known to all functions following 
                            // the definition in this unit    

end.

Am nächsten kommt Delphi dem dynamischen Bereich durch das Funktionspaar RegisterClass()/GetClass(). Zur Verwendung siehe hier.

Nehmen wir an, dass die Zeit RegisterClass([TmyClass]) aufgerufen wird, um eine bestimmte Klasse zu registrieren, kann nicht durch Lesen des Codes vorhergesagt werden (es wird in einer vom Benutzer aufgerufenen Schaltflächenklickmethode aufgerufen), Code, der GetClass(‘TmyClass’) aufruft, wird ein Ergebnis erhalten oder nicht. Der Aufruf von RegisterClass() muss sich nicht im lexikalischen Bereich der Unit befinden, die GetClass() verwendet;

Eine weitere Möglichkeit für dynamischen Umfang sind Anonyme Methoden (Closures) in Delphi 2009, da sie die Variablen ihrer aufrufenden Funktion kennen. Es folgt dem Aufrufpfad von dort nicht rekursiv und ist daher nicht vollständig dynamisch.

  • Tatsächlich ist private in der gesamten Einheit zugänglich, in der die Klasse definiert ist. Aus diesem Grund wurde in D2006 „Strict private“ eingeführt.

    – Marco van de Voort

    26. Juni 2009 um 22:34 Uhr

  • +1 für einfache Sprache (im Gegensatz zu komplizierter Sprache und Beispielen ohne viel Beschreibung)

    – Knallt

    27. April 2010 um 17:48 Uhr

1646635526 214 Was ist lexikalischer Umfang
Peter Mortensen

Ich liebe die voll funktionsfähigen, sprachunabhängigen Antworten von Leuten wie @Arak. Da diese Frage markiert wurde JavaScript Ich möchte jedoch einige Anmerkungen hinzufügen, die für diese Sprache sehr spezifisch sind.

In JavaScript sind unsere Auswahlmöglichkeiten für den Bereich:

  • so wie es ist (keine Bereichsanpassung)
  • lexikalisch var _this = this; function callback(){ console.log(_this); }
  • gebunden callback.bind(this)

Ich denke, es ist erwähnenswert, dass JavaScript hat nicht wirklich dynamische Scoping. .bind passt die an this Schlüsselwort, und das ist nah, aber technisch nicht dasselbe.

Hier ist ein Beispiel, das beide Ansätze demonstriert. Sie tun dies jedes Mal, wenn Sie eine Entscheidung darüber treffen, wie Callbacks zu bereichern sind, damit dies für Promises, Event-Handler und mehr gilt.

Lexikalisch

Hier ist, was Sie nennen könnten Lexical Scoping von Callbacks in JavaScript:

var downloadManager = {
  initialize: function() {
    var _this = this; // Set up `_this` for lexical access
    $('.downloadLink').on('click', function () {
      _this.startDownload();
    });
  },
  startDownload: function(){
    this.thinking = true;
    // Request the file from the server and bind more callbacks for when it returns success or failure
  }
  //...
};

Gebunden

Eine andere Art des Umfangs ist die Verwendung Function.prototype.bind:

var downloadManager = {
  initialize: function() {
    $('.downloadLink').on('click', function () {
      this.startDownload();
    }.bind(this)); // Create a function object bound to `this`
  }
//...

Diese Methoden sind, soweit ich weiß, verhaltensmäßig gleichwertig.

  • Tatsächlich ist private in der gesamten Einheit zugänglich, in der die Klasse definiert ist. Aus diesem Grund wurde in D2006 „Strict private“ eingeführt.

    – Marco van de Voort

    26. Juni 2009 um 22:34 Uhr

  • +1 für einfache Sprache (im Gegensatz zu komplizierter Sprache und Beispielen ohne viel Beschreibung)

    – Knallt

    27. April 2010 um 17:48 Uhr

Lexikalischer Geltungsbereich bedeutet, dass in einer verschachtelten Gruppe von Funktionen, Die inneren Funktionen haben Zugriff auf die Variablen und andere Ressourcen ihres übergeordneten Geltungsbereichs.

Das bedeutet, dass die Funktionen des Kindes lexikalisch an den Ausführungskontext ihrer Eltern gebunden sind.

Der lexikalische Geltungsbereich wird manchmal auch als bezeichnet statischer Geltungsbereich.

function grandfather() {
    var name="Hammad";
    // 'likes' is not accessible here
    function parent() {
        // 'name' is accessible here
        // 'likes' is not accessible here
        function child() {
            // Innermost level of the scope chain
            // 'name' is also accessible here
            var likes="Coding";
        }
    }
}

Was Sie am lexikalischen Geltungsbereich bemerken werden, ist, dass er vorwärts arbeitet, was bedeutet, dass auf den Namen durch die Ausführungskontexte seiner untergeordneten Elemente zugegriffen werden kann.

Aber es funktioniert nicht rückwärts zu seinen Eltern, was bedeutet, dass die Variable likes kann von seinen Eltern nicht aufgerufen werden.

Dies sagt uns auch, dass Variablen mit demselben Namen in verschiedenen Ausführungskontexten von oben nach unten im Ausführungsstapel Vorrang erhalten.

Eine Variable mit einem ähnlichen Namen wie eine andere Variable in der innersten Funktion (oberster Kontext des Ausführungsstapels) hat eine höhere Priorität.

Quelle.

963690cookie-checkWas ist lexikalischer Umfang?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy