Was ist falsch an der Verwendung einer etikettierten Anweisung im globalen Code?

8

Ich habe gerade die Quelle von JSLint durchsucht und diesen Codeabschnitt bemerkt:

%Vor%

Der interessante Teil ist der funct === global_funct Vergleich. Wenn das folgende Snippet durch JSLint ausgeführt wird, wird ein "Unexpected label" -Fehler ausgelöst, da sich die beschriftete Anweisung im globalen Ausführungskontext befindet (ich weiß, dass es ein dummes Beispiel ist. Hier ist eine Geige .):

%Vor%

Wenn Sie das gleiche Snippet in eine Funktion einfügen, ist JSLint damit vollkommen zufrieden und es wird kein Fehler ausgegeben, wenn es auf das Label trifft. Hier ist eine Geige mit Code, der JSLint passieren wird. Der Code kann in die Online-Version von JSLint eingefügt werden, wenn Sie es ausprobieren möchten.

Also meine Frage: Ist etwas falsch mit der Verwendung einer beschrifteten Aussage im globalen Code oder ist es nur eine andere persönliche Entscheidung von Crockford?

    
James Allardice 17.07.2012, 20:35
quelle

1 Antwort

3

Nach einigen Untersuchungen über das Verhalten von etikettierten Aussagen denke ich, dass dies tatsächlich nur eine Entscheidung von Crockford ist, die tatsächlich keine wirkliche Grundlage hat. Soweit ich das beurteilen kann, gibt es keine Situation, die zu einem Namenskonflikt mit Labels im globalen Bereich führen könnte (und das schien der Hauptgrund dafür zu sein, warum JSLint dies verbietet - siehe Kommentare zu der Frage) / p>

In der ES5-Spezifikation wird im Abschnitt über beschriftete Anweisungen Folgendes angegeben:

  

Der Produktion Bezeichner: Anweisung wird durch Hinzufügen ausgewertet    Bezeichner für den Bezeichnersatz von Anweisung und dann für die Auswertung Anweisung .

     

...

     

Vor der Auswertung eines LabelledStatement wird die enthaltene Anweisung als leerer Beschriftungssatz betrachtet, es sei denn, es handelt sich um IterationStatement oder IterationStatement a SwitchStatement . In diesem Fall wird davon ausgegangen, dass es über einen Labelsatz verfügt, der aus dem einzelnen Element empty besteht.

Ich nehme an, dass jede Aussage einen Label-Satz hat. Label-Bezeichner sind unabhängig von Variablen- und Funktionsbezeichnern. Daher ist es syntaktisch zulässig, ein Label mit demselben Bezeichner wie eine Variable im selben Bereich zu verwenden. Mit anderen Worten, das ist gültig:

%Vor%

Da jede Anweisung ihre eigene Label-Menge hat, ist dies auch gültig:

%Vor%

Da Sie jede Anweisung beschriften können (es ist sinnlos, aber es ist möglich), können Sie eine beschriftete Anweisung beschriften:

%Vor%

Wenn dies der Fall ist, gibt die Spezifikation folgendes an:

  

Wenn das LabelledStatement selbst über einen nicht leeren Beschriftungssatz verfügt, werden diese Beschriftungen auch dem Beschriftungssatz von "Statement before" hinzugefügt   es auswerten.

Im obigen Snippet enthält der Label-Set der for -Anweisung zwei Labels ( another und label ). Es ist möglich, entweder dieser Labels innerhalb der for -Anweisung zu brechen.

Und schließlich gibt die Spezifikation auch an (Hervorhebung hinzugefügt):

  

Markierte Anweisungen werden nur in Verbindung mit dem Label break verwendet.   und continue -Anweisungen. ECMAScript hat keine goto -Anweisung .

Auf der Grundlage all dessen kann ich mir keinen möglichen Weg vorstellen, wie Labels im globalen Code mit anderem globalen Code kollidieren könnten. Natürlich ist es sehr unwahrscheinlich, dass Sie ein Programm wünschen, das mehrere Labels mit demselben Bezeichner enthält, und JSLint verhindert dies bereits, indem es einen "Label ist bereits definiert" -Fehler ausgibt. Aber ich denke nicht, dass es einen Unterschied geben sollte, wie es beschriftete Anweisungen im globalen Ausführungskontext behandelt.

    
James Allardice 18.07.2012, 09:14
quelle

Tags und Links