Geschrieben von Lewis Cianci✏️
Sie sind also ein JavaScript-Entwickler? Schön zu hören – was gibt dieser Code Ihrer Meinung nach zurück? Und ja, es ist eine Fangfrage:
function returnSomething() { return { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
In fast jeder anderen Sprache – C#, Java, die Liste geht weiter – würden wir das Objekt mit JavaScript Expert zurückbekommen. Und man könnte meinen, dass wir in JavaScript das gleiche Ergebnis erhalten würden.
Lassen Sie es mich jedoch bereuen, fügen Sie dies in Ihre Entwicklungskonsole ein und führen Sie dann die Funktion aus. Es ist fast unglaublich, dass es undefiniert zurückgibt.
Als Softwareentwickler zu arbeiten bedeutet, dass Sie dafür verantwortlich sind, wie Ihre App funktioniert, egal ob sie gut oder schlecht funktioniert. Eine wesentliche Einschränkung dabei sind die Tools, die Sie verwenden möchten. Wenn Sie verstehen, was Sie verwenden, treffen Sie hoffentlich gute Entscheidungen bei der Gestaltung Ihrer Software.
JavaScript ist einzigartig, weil es die Sprache der Wahl so vieler neuer Softwareentwickler ist. Möchten Sie eine mobile App schreiben? Verwenden Sie einfach React Native und JavaScript. Desktop-App? Reagieren Sie nativ und JavaScript. Eine Cloud-Funktion, die irgendwo ausgeführt werden kann? Node.js und, Sie haben es erraten, JavaScript.
Da es JavaScript jedoch schon so lange gibt, gibt es eine Menge Tricks und Fallstricke. Einige davon reichen von leicht amüsant bis hin zu „Nichts von meinem Code funktioniert und ich weiß nicht warum“-Schweregrad.
Und selbst wenn wir in einer Zeit leben würden, in der der Internet Explorer 6 seine Blütezeit erlebte, wäre es einfach zu spät, einige dieser Designentscheidungen zu korrigieren, da wir dadurch zu viel vom Web zerstören würden. Wenn das damals der Fall wäre, stellen Sie sich vor, wir würden es heute versuchen! ??
Wieso funktioniert JavaScript nicht so, wie wir es vielleicht erwarten würden? Werfen wir einen Blick darauf.
Das eingangs aufgeführte Beispiel wird von JavaScript-Interpretern akzeptiert, liefert jedoch nicht das erwartete Ergebnis. Der Grund liegt in der automatischen Semikolon-Injektion.
Einige Sprachen, wie z. B. C#, sind dogmatisch, jede Zeile mit einem Semikolon zu beenden. JavaScript verwendet auch Semikolons, um das Ende einer Zeile anzuzeigen, aber das Semikolon ist eigentlich optional. „Optional“ bedeutet, dass JavaScript eine Reihe komplexer Regeln anwendet, um herauszufinden, ob dort ein Semikolon hätte stehen sollen oder nicht.
Da im Beispiel zu Beginn die öffnende Klammer nicht in derselben Zeile wie der Zeilenumbruch steht, fügt ASI dort eine ein. Was JavaScript betrifft, sieht unser Code tatsächlich so aus:
function returnSomething() { return ; // <-- semicolon inserted by ASI, remainder of function not evaluated. { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
Dies lässt sich vermeiden, indem die öffnende Klammer in derselben Zeile wie ein Return steht. Und obwohl Semikolons in JavaScript technisch gesehen optional sind, wird es Ihnen auf lange Sicht schaden, mit diesem Konzept zu arbeiten.
Wenn Sie ein Vorstellungsgespräch haben und JS schreiben müssen und es ohne Semikolons schreiben, basierend auf der Begründung „aber sie sind optional“, wird es viel Papierkram und Gelächter geben. Tu es einfach nicht.
Stellen wir uns vor, wir haben ein einfaches Array:
function returnSomething() { return { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
Wir wissen, dass wir mit Arrays Pop, Push, Anhängen und tun können, was immer wir wollen. Wir wissen aber auch, dass JavaScript uns wie andere Sprachen den Zugriff auf Array-Elemente über den Index ermöglicht.
Das Ungewöhnliche an JavaScript ist jedoch, dass Sie Elemente auch nach Array-Index festlegen können, wenn das Array diesen Index noch nicht einmal erreicht hat:
function returnSomething() { return ; // <-- semicolon inserted by ASI, remainder of function not evaluated. { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
Ich habe jedoch eine gute Frage an Sie: Wie lang ist ein Array, wenn Sie nur drei Elemente festgelegt haben? Möglicherweise nicht intuitiv, ist es 101. Einerseits ist es vernünftig, dass die Array-Elemente 2 bis 99 undefiniert sind, andererseits legen wir nur drei Objekte fest, nicht 100.
Warum ist das wichtig?
Vielleicht rollen Ihnen die Augen aus dem Kopf und Sie sagen: „Okay, Lewis, Sie weisen manuell Elemente einem Array zu und beobachten, wie sich die Räder lösen. Das macht dich komisch, nicht JavaScript.“
Ich würde diese Position verstehen. Aber stellen Sie sich für einen Moment vor, Sie tun etwas in einer verschachtelten for-Schleife und wählen den falschen Iterator oder führen eine komplizierte Berechnung durch.
Irgendwann wird sich der Denkprozess „Warum erhalte ich das erwartete Ergebnis, das erwartete Ergebnis, das undefinierte, das erwartete Ergebnis“ in Wahnsinn und schon bald in Tränen verwandeln! Sie wussten nicht, dass Ihr Array auf magische Weise wuchs, um Ihren Zielen gerecht zu werden.
Das einzige Problem war, dass Sie versucht haben, das Falsche zu tun.
Um es mit einer anderen Sprache wie C# zu vergleichen (ohne besonderen Grund): Arrays haben eine feste Länge. Wenn Sie ein Array erstellen, müssen Sie eine Länge definieren. Selbst für andere dynamische Sammlungsobjekte wie List Ausnahmen sind nicht schön, aber wahrscheinlich das Richtige. Ich meine, wollten Sie sonst ein Schweizer Käse-Array erstellen? Hat jemand vor, das zu tun? Hoffentlich nicht. Es sind nur Schweizer Käse-Arrays, wenn die Entwickler aus der Schweiz kommen. Ansonsten ist es einfach nur eine blitzsaubere Programmierung. Wir wissen, dass wir in JavaScript Prototypen neue Funktionen zuweisen können. So können wir Strings oder Arrays „besondere Kräfte“ verleihen. Das ist natürlich eine schreckliche Praxis, denn es bedeutet, dass sich unser String-Prototyp anders verhält als andere, was vielen Entwicklern schon jetzt großen Kummer bereitet. So können wir zum Beispiel Folgendes tun: Und dann können wir ein String-Objekt erstellen: Und es würde false zurückgeben. Es ist süß, dass wir unsere Funktionen immer einfach zufällig in die werkseitig definierte Implementierung der Funktionsweise eines Strings einfügen können. Sicher, all diese guten Leute haben sich den Rücken gekehrt und Zehntausende von Stunden damit verbracht, JavaScript in der TC39-Spezifikation zu definieren, aber lassen Sie sich dadurch nicht davon abhalten, Ihre Zufallsfunktionen so einzubauen, wie Sie es für richtig halten. Wenn wir mit dieser bestimmten Art von Schmerz nicht zufrieden sind, können wir komplexen Objekten auch nach Belieben neue Funktionen zuweisen und so sicherstellen, dass unser Code eine ganz besondere Form von Unsinn ist, den nur Sie selbst und Gott verstehen : Allerdings geht der gute Wille bei Objektprimativen auf überraschende Weise zur Neige: Warum ist das wichtig? In anderen stark typisierten Sprachen müssen wir den Typ der Daten definieren, die wir speichern, bevor wir sie speichern können. Bei JavaScript gibt es diese Art von Einschränkung nicht, und es schiebt Objekte gerne von ihrem definierten Typ weg, um zu versuchen, dass sie gut zusammenspielen. Einerseits hält es uns davon ab, Variablen hin und her in ihre jeweiligen Typen umzuwandeln. So ist es praktisch: Warum ist das wichtig? Bei den Sprachen, die wir heute verwenden, ist ein wichtiger Aspekt das sogenannte „Funktionsheben“. Im Wesentlichen bedeutet dies, dass Sie Ihre Funktionen in Ihre Datei schreiben können, wo immer Sie möchten, und dass Sie sie aufrufen können, bevor die Funktionen deklariert werden: Das ist praktisch, weil wir unseren Code nicht manuell neu anordnen müssen, damit er funktioniert. Aber es gibt mehr als eine Möglichkeit, eine Funktion zu beschreiben. In diesem Beispiel haben wir dazu eine Funktionsdeklaration verwendet. Wir können auch einen Funktionsausdruck verwenden: Warum ist das wichtig? In anderen Sprachen können Objekteigenschaften zugewiesen werden oder sie können null sein. null gibt an, dass die Eigenschaft nicht zugewiesen ist. Es ist einfach, in unseren Köpfen eine Gleichsetzung vorzunehmen: Entweder gibt es dort ein Objekt oder es ist null. Wenn wir möchten, können wir Eigenschaften auch wieder auf null zurückführen. JavaScript verkompliziert diese Landschaft, indem es null und auch undefiniert hat. Aber es ist doch alles dasselbe, oder? Entweder man hat einen Ball in der Hand, oder man hat ihn nicht. Es überrascht nicht, dass nicht alles das Gleiche ist. In JavaScript gibt null das absichtliche Fehlen eines Werts an, während undefiniert das implizite Fehlen eines Werts angibt. Ob es also beabsichtigt, explizit oder in den Himmel geschrieben ist, Tatsache ist, dass kein Wert = kein Wert ist, oder? Wiederum geht die Gleichung leider nicht auf. Nun, was ist die Art von Undefiniert? Okay, und was ist der Typ Null? ? es ist ein Objekt. In JavaScript sind also der Typ eines komplexen Objekts und Null derselbe – beide sind Objekt: Warum ist das wichtig? Die heutige immense Beliebtheit von JavaScript als Sprache steht außer Frage. Da die Zeit vergeht und andere Ökosysteme wie npm weiterhin eine große Anzahl von Paketen hosten, wird JavaScript immer beliebter. Aber was getan ist, ist getan. Egal wie seltsam es ist, dass null ein Objekt ist oder dass JavaScript Semikolons dort einfügt, wo es passt, diese Systeme werden wahrscheinlich nie veraltet, geändert oder entfernt. Anekdotisch würde ich sagen, dass eine Deaktivierung der automatischen Semikolon-Injektion über Nacht wahrscheinlich zu einem größeren weltweiten Ausfall führen würde als das CrowdStrike-Update. Natürlich würde die Änderung einer davon verheerende Auswirkungen auf das Web haben. Es ist tatsächlich sicherer und wahrscheinlich praktischer, die Entwickler auf diese besonderen Sprachmängel aufmerksam zu machen, als tatsächlich zurückzugehen und die ursprünglichen Probleme zu lösen. Treffen Sie also gute Entscheidungen und vergessen Sie nicht, Semikolons zu verwenden! Das Debuggen von Code ist immer eine mühsame Aufgabe. Aber je besser Sie Ihre Fehler verstehen, desto einfacher ist es, sie zu beheben. LogRocket ermöglicht es Ihnen, diese Fehler auf neue und einzigartige Weise zu verstehen. Unsere Frontend-Überwachungslösung verfolgt die Benutzerinteraktion mit Ihren JavaScript-Frontends, um Ihnen die Möglichkeit zu geben, genau zu sehen, was der Benutzer getan hat, was zu einem Fehler geführt hat. LogRocket zeichnet Konsolenprotokolle, Seitenladezeiten, Stack-Traces, langsame Netzwerkanforderungen/-antworten mit Header-Körpern, Browser-Metadaten und benutzerdefinierten Protokollen auf. Es wird nie einfacher sein, die Auswirkungen Ihres JavaScript-Codes zu verstehen! Probieren Sie es kostenlos aus. Das obige ist der detaillierte Inhalt vonSechs Dinge, die Sie möglicherweise nicht über JavaScript wissen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!
Das Hinzufügen von Eigenschaften zu Primativen wird ignoriert
function returnSomething()
{
return
{
name: 'JavaScript Expert'
contactMethod: 'Shine batsign at sky'
}
}
function returnSomething()
{
return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
{
name: 'JavaScript Expert'
contactMethod: 'Shine batsign at sky'
}
}
Unsere Objekte auf diese Weise zu komponieren ist natürlich eine schreckliche Idee, aber da wir uns diesem Verrat verschrieben haben, kommt uns JavaScript in unserer Bitte entgegen. Unser testObject übernimmt die neue Funktion, die wir ihm hinzugefügt haben.
Der Interpreter erkennt unseren Versuch, dem String-Primativ eine Funktion zuzuweisen. Es gibt sogar die Funktion an uns zurück. Aber wenn wir dann versuchen, es aufzurufen, erhalten wir einen TypeError: testString.onlyFalse ist keine Funktion. Wenn dies nicht möglich ist, erwarten Sie normalerweise, dass dies bei der Zuweisung und nicht beim Funktionsaufruf ausgelöst wird.
Im Guten wie im Schlechten ist JavaScript eine äußerst flexible und dynamische Sprache. Diese Flexibilität ermöglicht es uns, Funktionen zu erstellen, die in anderen Sprachen nicht möglich sind. Wenn etwas nicht funktioniert hat, müssen wir mit einer Ausnahme rechnen. Wenn JavaScript diesen unangenehmen Befehl annimmt und sagt: „Äh, okay“ und es dann vergisst, ändert sich diese grundlegende Erwartung.
Geben Sie Zwang ein
Das Gleiche gilt sogar für boolesche Werte:
Dieser Ansatz ist völlig vernünftig und gültig, bis wir uns auf das Tabu-Ritual „Addition“ einlassen wollen. Was passiert, wenn wir versuchen, „1“ und 1 zusammenzuzählen? In welche Richtung geht der Typenzwang?
Der Wahnsinn Heiterkeit vervielfacht sich, wenn wir Bool zur Party mitbringen:
Oh – liegt es daran, dass ein Bool unter der Haube irgendwie eine Zahl ist?
Nein. Es ist ein boolescher Wert. JavaScript schneidet aus Gründen die lästigen Kanten des Quadrats ab, um es in dieses runde Loch zu passen.
Wenn Sie etwas so Grundlegendes wie das Addieren von Zahlen tun, können unterschiedliche Ergebnisse zu seltsamen Fehlern führen. Es ist eine gute Erinnerung, sich bei Vergleichen an die Dreifachgleichheit (===) zu halten, da das Wechseln zwischen Typen möglicherweise nicht das gewünschte Ergebnis liefert.
Funktion Heben
function returnSomething()
{
return
{
name: 'JavaScript Expert'
contactMethod: 'Shine batsign at sky'
}
}
function returnSomething()
{
return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
{
name: 'JavaScript Expert'
contactMethod: 'Shine batsign at sky'
}
}
In beiden Fällen gibt es keinen großen Unterschied zwischen der Deklaration von Funktionen, aber wenn Sie die falsche Option auswählen, können Sie Ihre Funktion nicht aufrufen, es sei denn, Sie rufen sie auf, nachdem Sie sie deklariert haben.
Null ist ein Objekt
JavaScript verfügt nicht über ein integriertes robustes Typprüfungssystem und es stehen nur eine Handvoll primärer Typen zur Auswahl. Daher kann es schwierig werden, „typeof“ zu verwenden, um zu verstehen, was in unserer Variablen enthalten ist. Wenn unsere Variable ein gültiges Objekt enthält, erhalten wir das Objekt. Aber wenn es null ist, erhalten wir immer noch ein Objekt. Es ist kontraintuitiv zu glauben, dass eine Nullreferenz ein Objekt ist.
Abschluss
LogRocket: JavaScript-Fehler einfacher beheben, indem Sie den Kontext verstehen