Ursprüngliche Frage:
JSHint beschwert sich, wenn mein JavaScript eine Funktion aufruft, die weiter unten auf der Seite definiert ist als der Aufruf. Meine Seite ist jedoch für ein Spiel und es werden keine Funktionen aufgerufen, bis das Ganze heruntergeladen wurde. Warum erscheinen die Bestellfunktionen in meinem Code?
EDIT: Ich glaube, ich habe die Antwort gefunden.
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Ich stöhne innerlich. Sieht so aus, als müsste ich einen weiteren Tag damit verbringen, sechstausend Codezeilen neu zu bestellen. Die Lernkurve mit Javascript ist überhaupt nicht steil, aber sehr lang.
javascript
function
jslint
jshint
Chris Tolworthy
quelle
quelle
Antworten:
tl; dr Wenn Sie nichts anrufen, bis alles geladen ist, sollte es Ihnen gut gehen.
Bearbeiten: Für eine Übersicht, die auch einige ES6-Deklarationen (
let
,const
) abdeckt : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_CheatsheetDieses seltsame Verhalten hängt davon ab
Hier sind einige Beispiele.
Dies liegt an etwas, das als Heben bezeichnet wird !
Es gibt zwei Möglichkeiten , um Funktionen zu definieren: Funktionsdeklaration und Funktion Ausdruck . Der Unterschied ist ärgerlich und winzig, also sagen wir einfach etwas Falsches: Wenn Sie es so schreiben
function name() {}
, ist es eine Deklaration , und wenn Sie es so schreibenvar name = function() {}
(oder eine anonyme Funktion, die einer Rückgabe zugewiesen ist, solche Dinge), ist es das eine Funktion Ausdruck .Schauen wir uns zunächst an, wie mit Variablen umgegangen wird:
Nun, wie Funktionsdeklarationen werden behandelt:
Die
var
Anweisungen "werfen" die Erstellung vonfoo
ganz nach oben, weisen ihr jedoch noch keinen Wert zu. Als nächstes folgt die Funktionsdeklaration, und schließlich wird ein Wert zugewiesenfoo
.Und was ist damit?
Nur die Deklaration von
foo
wird nach oben verschoben. Die Zuordnung erfolgt erst nach dem Anruf beibar
, wo es war, bevor das gesamte Heben stattgefunden hat.Und schließlich der Kürze halber:
Nun, was Funktion Ausdrücke ?
Genau wie reguläre Variablen, zuerst
foo
wird erklärt am höchsten Punkt des Bereichs, dann wird ein Wert zugewiesen.Mal sehen, warum das zweite Beispiel einen Fehler auslöst.
Wie wir zuvor gesehen haben, wird nur das Erstellen von
foo
angehoben, die Zuweisung erfolgt dort, wo sie im "ursprünglichen" (nicht angehobenen) Code enthalten ist. Wennbar
aufgerufen wird, wird ihm vorherfoo
ein Wert zugewiesen, alsofoo === undefined
. Jetzt im Funktionskörper vonbar
ist es so, als ob Sie es tunundefined()
, was einen Fehler auslöst.quelle
Der Hauptgrund ist wahrscheinlich, dass JSLint die Datei nur einmal durchläuft, sodass es nicht weiß, dass Sie eine solche Funktion definieren werden.
Wenn Sie die Funktionsanweisungssyntax verwendet haben
Es gibt eigentlich überhaupt keinen Unterschied, wo Sie die Funktion deklarieren (sie verhält sich immer so, als ob die Deklaration am Anfang steht).
Auf der anderen Seite, wenn Ihre Funktion wie eine reguläre Variable festgelegt wurde
Sie müssen sicherstellen, dass Sie es nicht vor der Initialisierung aufrufen (dies kann tatsächlich eine Fehlerquelle sein).
Da das Neuanordnen von Tonnen von Code kompliziert ist und selbst eine Fehlerquelle sein kann, würde ich Ihnen empfehlen, nach einer Problemumgehung zu suchen. Ich bin mir ziemlich sicher, dass Sie JSLint den Namen globaler Variablen im Voraus mitteilen können, damit es sich nicht über nicht deklarierte Inhalte beschwert.
Geben Sie einen Kommentar zum Anfang der Datei ein
Oder Sie können dort ein Textfeld verwenden. (Ich denke auch, dass Sie dies in den Argumenten an die innere jslint-Funktion übergeben können, wenn Sie sich damit einmischen können.)
quelle
Es gibt viel zu viele Leute, die willkürliche Regeln festlegen, wie JavaScript geschrieben werden soll. Die meisten Regeln sind völliger Müll.
Das Heben von Funktionen ist eine Funktion in JavaScript, da dies eine gute Idee ist.
Wenn Sie eine interne Funktion haben, die häufig von inneren Funktionen genutzt wird, ist das Hinzufügen am Anfang der äußeren Funktion eine akzeptable Art, Code zu schreiben. Sie hat jedoch den Nachteil, dass Sie die Details durchlesen müssen, um zu dem zu gelangen, was erreicht werden soll die äußere Funktion tut.
Sie sollten sich in Ihrer gesamten Codebasis an ein Prinzip halten, indem Sie entweder private Funktionen an die erste oder letzte Stelle in Ihrem Modul oder Ihrer Funktion setzen. JSHint ist gut, um die Konsistenz zu erzwingen, aber Sie sollten die .jshintrc ABSOLUT an Ihre Bedürfnisse anpassen und Ihren Quellcode NICHT an die verrückten Codierungskonzepte anderer Leute anpassen.
Ein Codierungsstil, den Sie möglicherweise in freier Wildbahn sehen, sollten Sie vermeiden, da er Ihnen keine Vorteile und nur mögliche Refactoring-Schmerzen bietet:
Genau diese Funktion soll das Heben von Funktionen vermeiden. Lernen Sie einfach die Sprache und nutzen Sie ihre Stärken.
quelle
Es wird nur die Funktionsdeklaration gehisst, nicht der Funktionsausdruck (Zuweisung).
quelle