Wenn wir
haben %Vor%Wird Javascript irgendwelche Fehler werfen?
Aktualisieren
Warum ist das?
Sollte Javascript nicht in der Lage sein zu sagen, was Sie auf dem Weg, wie Sie es nennen, sind?
Es sollte Ihnen eine TypeError
Ausnahme geben - um zu versuchen, ein Objekt aufzurufen - das in der Firebug-Konsole beobachtete Verhalten ist nicht richtig ...
FunctionDeclaration
s sind hochgezogen oben im umschließenden Bereich, Ihr Code wird tatsächlich in dieser Reihenfolge ausgeführt:
Bei der Eingabe in einen Ausführungskontext wird der Vorgang Variable Instanziierung (auch bekannt als Deklaration Binding Instantiierung in ES5) definiert die Eigenschaften auf der Activation Object (AO, dies ist ein nicht erreichbares Objekt, das Identifier von Variablen, Funktionsdeklarationen und Funktionsargumenten im lokalen Bereich enthält ) in folgender Reihenfolge:
FormalParameterList
Identifikatoren (für Funktionscode ) FunctionDeclaration
Identifikatoren VariableDeclaration
Identifikatoren A VariableDeclaration
überschreibt nicht einen Bezeichner, der bereits in der AO definiert wurde (z. B. durch einen der ersten beiden Schritte), aber die Zuweisung wird dies zur Laufzeit tun.
Zum Beispiel:
%Vor%Wenn jedoch eine Zuweisung vorgenommen wird, wird der Wert des Bezeichners ersetzt, zum Beispiel:
%Vor% Im obigen Beispiel wird beim Aufruf der Funktion, aber vor der Ausführung des Codes, der foo
-Bezeichner für das Aktivierungsobjekt (auch bekannt als Variablenobjekt) eingerichtet.
Zuerst wird der Wert des Formalparameters zugewiesen, der Wert 'string'
, dann alle FunctionDeclaration
im Funktionskörper, eine Funktion mit dem Namen foo
wird gefunden, dann die foo
Kennung Zeigen Sie auf diese Funktion.
Danach werden alle Variablendeklarationen untersucht, wir haben eine mit dem Bezeichner foo
, aber ihr Wert wird in dieser Zeit respektiert - daran erinnert, dass die Funktion nicht ausgeführt wurde.
An diesem Punkt ist die Funktion bereit zur Ausführung, ihre lexikalische und variable Umgebung ist eingerichtet.
Das erste, was in der Funktion ausgeführt wird, ist die Zuweisung foo = {};
, die den Verweis auf die Funktion ersetzt, die wir vorher hatten.
Warum verhält es sich in anderen Browsern und Firefox anders?
Weil:
Da Firebug Code durch Wrapping innerhalb einer with
-Anweisung auswertet, bewirkt dies, dass FunctionDeclaration
im Anweisungskontext ausgewertet wird - eine Funktionserklärung von Mozilla -.
Um das Verhalten der Function-Anweisung in Mozilla-Implementierungen anzuzeigen, betrachten Sie das folgende Beispiel:
%Vor% In Mozilla erhalten Sie 'true!'
, während Sie in anderen Implementierungen 'false??!'
- sogar auf IE - erhalten.
Das liegt daran, dass die Funktionsdefinition zur Laufzeit im Anweisungskontext (in der Seite der wahren Verzweigung von if
) erstellt wurde, während in anderen Implementierungen die Funktionsdeklarationen bei parse time .
Das obige Beispiel sollte tatsächlich eine SyntaxError
-Ausnahme bei jeder Implementierung erzeugen, aber das passiert bei keinem von ihnen ...
A FunctionDeclaration
sollte nur im globalen Code oder direkt im FunctionBody einer Funktion erlaubt sein.
A viele Leute verwenden synonym die Begriffe Funktionserklärung und Funktionserklärung, aber das ist völlig falsch, ECMAScript definiert keine Funktionserklärung, ist ein Nicht-Standard-Funktion .
Die Spezifikation enthält eine kurze Anmerkung zu diesem Thema:
HINWEIS: Mehrere weit verbreitete Implementierungen von ECMAScript unterstützen bekanntermaßen die Verwendung von FunctionDeclaration als Anweisung. Es gibt jedoch signifikante und unüberbrückbare Variationen unter den Implementierungen in der Semantik, die auf solche Funktionsdeklarationen angewendet werden. Aufgrund dieser unvereinbaren Unterschiede führt die Verwendung einer Funktionserklärung als Anweisung zu einem Code, der zwischen Implementierungen nicht zuverlässig übertragbar ist. Es wird empfohlen, dass ECMAScript-Implementierungen diese Verwendung von FunctionDeclaration entweder verbieten oder eine Warnung ausgeben, wenn eine solche Verwendung auftritt. Zukünftige Ausgaben von ECMAScript können alternative tragbare Mittel zum Deklarieren von Funktionen in einem Anweisungskontext definieren.
Versuchen Sie, Ihren Code im globalen Ausführungskontext auszuführen - in einem einfachen <script>
-Element - und Sie werden sehen, dass er auch in Firefox abstürzt:
Sie finden das obige Beispiel hier , stellen Sie sicher, dass Sie die Firebug-Konsole öffnen, und Sie werden den gleichen Fehler sehen, den Sie erhalten auf anderen Browsern.
Ihr function randomname()
definiert den randomname
-Bezeichner neu und verliert damit den Verweis auf das Objekt, das Sie zuvor erstellt haben. Es sieht vielleicht klarer aus:
Es ist wie:
%Vor%ist ungefähr dasselbe:
%Vor%Es ist nicht 100% identisch, da man sich bei der ersten Syntax auf Funktionen "in der Zukunft" beziehen kann, aber so funktioniert es im Grunde. Es gibt nur einen Namensraum für Funktionen und Variablen, da Funktionen Variablen zugewiesen werden.
Funktion ist auch tatsächlich ein Objekt ( Erstklassiges Objekt ) in JavaScript.
Sie können also so etwas tun.
%Vor%Und dann können Sie Folgendes tun:
%Vor%Verzeihen Sie meine Pedant Antwort. Ihre Frage ist ein wenig verwirrend, oder ist das eine knifflige Frage? In der zweiten Zeile hast du geschrieben
%Vor%Wenn das Ihr Punkt ist, dann ist es eine illegale Aussage und wird definitiv eine Ausnahme auslösen. Aber wenn dein Punkt in der vierten Zeile ist, in der du den gleichen Namen benutzt hast.
Beachten Sie, dass Sie
geschrieben haben %Vor%statt
%Vor%Ich weiß nicht warum, aber weil Sie eine Zukunftsfunktion verwendet haben, können Sie keine bereits vorhandenen Namen überschreiben. Daher ist der Zufallsname immer noch ein Hash anstelle einer Funktion, wodurch eine Ausnahme ausgelöst wird.
Meine Frage ist, was passiert mit der Zufallsfunktion? Wie können wir es nennen? Ist es eine verschwendete Ressource? Als allgemeine Regel verwende ich immer
%Vor%Vorlage, so dass ich immer sicher bin, dass Namenskonflikte nicht passieren werden, so dass ich nie darauf stoße.
Ich weiß, das ist ein alter Beitrag, aber ich habe ein Beispiel dafür gefunden, wie es funktioniert.
Tatsächlich glaube ich, dass sequelize.js es mit folgendem Code macht:
%Vor% Sie können es in ihren Dokumenten für Datentypen sehen: Ссылка . Beachten Sie Sequelize.STRING
und Sequelize.STRING(1234)
Tags und Links javascript