Was genau ist Typenzwang in Javascript?
Zum Beispiel bei der Verwendung von ==anstelle von ===?
Was genau ist Typenzwang in Javascript?
Zum Beispiel bei der Verwendung von ==anstelle von ===?
Antworten:
Typzwang bedeutet, dass, wenn die Operanden eines Operators unterschiedliche Typen sind, einer von ihnen in einen "äquivalenten" Wert des Typs des anderen Operanden konvertiert wird. Wenn Sie zum Beispiel Folgendes tun:
boolean == integer
Der boolesche Operand wird in eine Ganzzahl konvertiert: falsewird 0, truewird 1. Dann werden die beiden Werte verglichen.
Wenn Sie jedoch den nicht konvertierenden Vergleichsoperator verwenden ===, erfolgt keine solche Konvertierung. Wenn die Operanden unterschiedlichen Typs sind, gibt dieser Operator zurück falseund vergleicht die Werte nur, wenn sie vom gleichen Typ sind.
===wenn ich vergleichen möchte, ob ein Wert einem anderen entspricht?
> , <?
Beginnen wir mit einer kurzen Einführung in Typsysteme, die Ihnen meiner Meinung nach helfen wird, die allgemeine Idee des Typzwangs zu verstehen.
Das Typsystem einer Sprache definiert Regeln, die uns mitteilen, welche Datentypen in dieser Sprache vorhanden sind und wie sie mit verschiedenen Operatoren kombiniert werden können. Eine solche Regel könnte beispielsweise festlegen, dass der Plus-Operator (+) nur auf Zahlen wirkt. Diese Regeln dienen in erster Linie dazu, Sie daran zu hindern, sich in den Fuß zu schießen. Aber was passiert, wenn der Programmierer diese Regel im Programm verletzt? Es gibt nichts , den Programmierer von der Eingabe zu verhindern {} + {}oder “hello” + 5in einem Programm , auch wenn die Sprache nicht denken , diese Ausdrücke keinen Sinn.
Was letztendlich in diesen Situationen passiert, hängt davon ab, wie streng die Sprache hinsichtlich ihrer Typregeln ist.
Ein Sprachtyp-System hat häufig eine von zwei Positionen, in denen Sie gegen seine Regeln verstoßen:
Sprachen mit Typsystemen, die in Bezug auf ihre Regeln die erste Position einnehmen, werden umgangssprachlich als "stark typisierte" Sprachen bezeichnet. Sie sind streng darauf bedacht, dass Sie nicht gegen die Regeln verstoßen. Diejenigen, die den zweiten Ansatz verfolgen (z. B. JavaScript), werden als "schwach typisierte" oder "lose typisierte" Sprachen bezeichnet. Natürlich können Sie gegen die Regeln verstoßen, aber wundern Sie sich nicht, wenn die in Ihrem Programm beschriebenen Datentypen gewaltsam konvertiert werden, um die Regeln einzuhalten. Dieses Verhalten ist bekannt als ... (Trommelwirbel) ... Zwang .
Schauen wir uns nun einige Beispiele in JavaScript an. Beginnen wir zunächst mit einem Ausdruck, der nicht zu Typenzwang führt.
5 + 5
Verwendung des Operators + mit zwei Zahlen, was vollkommen gültig ist. Das Programm behandelt + als "Hinzufügen" und fügt die beiden Zahlen glücklich hinzu. Keine Konvertierung notwendig.
Aber was ist mit …
[] + 5
Oh oh. +Kann in JavaScript bedeuten, zwei Zahlen hinzuzufügen oder zwei Zeichenfolgen zu verketten. In diesem Fall haben wir weder zwei Zahlen noch zwei Zeichenfolgen. Wir haben nur eine Nummer und ein Objekt. Nach den Typregeln von JavaScript ist dies logisch nicht sinnvoll. Da es verzeiht, dass Sie gegen die Regeln verstoßen, versucht es, anstatt es zum Absturz zu bringen, trotzdem einen Sinn daraus zu machen. Was macht JavaScript? Nun, es weiß, wie man Strings verkettet, also konvertiert es sowohl [] als auch 5 in Strings und das Ergebnis ist der String-Wert "5".
Was ist mit den Vergleichsoperatoren ==und ===? Warum gibt es zwei Vergleichsoperatoren?
==ist nicht immun gegen das Typkonvertierungsverhalten von JavaScript. Ausdrücke wie werden als 5 == “5”wahr ausgewertet, da JavaScript versucht, einen von ihnen so zu konvertieren, dass derselbe Datentyp verglichen wird.
In vielen Fällen ist dies nicht wünschenswert, da Sie wahrscheinlich wissen möchten, ob einige Daten, mit denen Sie vergleichen, von einem anderen Typ sind, damit Sie entscheiden können, was Sie dagegen tun möchten. Hier kommt der ===Operator ins Spiel. Bei Verwendung ===findet keine Typkonvertierung statt. Daher wird der Ausdruck 5 === “5”als falsch ausgewertet.
Wenn Sie in Python versuchen, beispielsweise Zeichenfolgen und Ganzzahlen hinzuzufügen, wird folgende Fehlermeldung angezeigt:
>>> "hi" + 10
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
In JavaScript ist dies jedoch nicht der Fall. Das 10wird in einen String konvertiert:
> "hi" + 10
"hi10"
"Typenzwang" ist nur eine ausgefallene Fehlbezeichnung für das oben Gesagte. Tatsächlich hat keine Sprache "Typen" im Sinne von Java oder C oder andere Sprachen mit statischen Typsystemen. Wie die Sprachen Interaktionen zwischen den verschiedenen nicht statisch typisierten Werten behandeln, ist eine Frage der Wahl und der Konvention.
Lassen Sie mich den Typenzwang anhand des folgenden Beispiels erklären
Typenzwang bedeutet, dass Javascript automatisch (im laufenden Betrieb) eine Variable von einem Datentyp in einen anderen konvertiert
Beispiel: 123 + "4"Löst im Allgemeinen einen Fehler aus, führt jedoch in Javascript aufgrund von Typenzwang zu 1234einer Zeichenfolge
if(23 == "23"){
console.log(" this line is inside the loop and is executed ");
}
Im obigen Code glaubt JavaScript aufgrund von Typenzwang, dass 23(Zahl) und "23"(Zeichenfolge) dasselbe sind. Dadurch wird die Bedingung erfüllt und das console.log gedruckt
Im anderen Fall
if(23 === "23"){
console.log(" this line is inside the loop and is NOT executed");
}
Für den ===Fall, dass Javascript keine Typenzwang ausführt und da 23eine Zahl und "23"ein String ist und aufgrund ===dieser beiden Datentypen unterschiedlich sind und dies zu einer falschen Bedingung führt. Das console.log wird nicht gedruckt
In einfachen Worten
In diesem Fall handelt =es sich um einen Zuweisungsoperator, der Werte wie var a = 3;usw. Zuweist
(Die folgenden Operatoren dienen zum Vergleich)
In diesem Fall ==konvertiert / erzwingt Javascript den Datentyp in einen anderen und vergleicht ihn dann.
In diesem Fall === konvertiert / erzwingt Javascript den Datentyp nicht
Um Fehler zu vermeiden und zu Debugging-Zwecken ===wird meistens verwendet
Bitte teilen Sie mir die Richtigkeit der oben genannten Informationen mit.
Typenzwang in Javascript tritt auf, wenn die Javascript-Engine eine bestimmte Operation ausführen muss, für die Daten eines bestimmten Typs erforderlich sind. Wenn die Engine auf Daten eines bestimmten Typs stößt, die für den Vorgang nicht zutreffen, werden die Daten zu einem bestimmten Typ gezwungen. Dies ist erforderlich, da Variablen in Javascript dynamisch typisiert werden. Dies bedeutet, dass einer bestimmten Variablen ein Wert eines beliebigen Typs zugewiesen werden kann.
if(1){
// 1 gets coerced to true
}
if(4 > '3') {
// 3 gets coerced into a number
}
44 == "44" // true, the string 44 gets converted to a nr
Beim Javascript-Zwang werden alle Werte konvertiert, mit trueAusnahme der folgenden Werte, zu denen erzwungen wird false:
console.log(!!""); // false
console.log(!!0); // false
console.log(!!null); // false
console.log(!!undefined); // false
console.log(!!NaN); // false
console.log(!!false); // false
Beachten Sie auch, dass im obigen Beispiel das Doppel! Operator wird verwendet. Das ! Der Markierungsoperator erzwingt einen Wert in einen Booleschen Wert mit dem entgegengesetzten Wert. Wir können diesen Operator zweimal verwenden, um einen beliebigen Wert in einen Booleschen Wert umzuwandeln.
a == bMittel Javascript bewerten wird agegen bbasierend auf , wenn die Werte gleich bewertet werden. false == 0Wird beispielsweise true auswerten, da 0 auch der Wert von Boolean false ist. Allerdings false === 0wird falsch beurteilen , weil streng zu vergleichen, 0 nicht die gleiche physikalische Größe wie falsch ist. Ein anderes Beispiel ist false == ''also im Grunde genommen ein lockerer Vergleich mit einem strengen Vergleich, da Javascript eine lose typisierte Sprache ist. Das heißt, Javascript versucht, die Variable basierend auf dem Kontext des Codes zu konvertieren, und dies hat zur Folge, dass die Dinge gleich werden, wenn sie nicht streng verglichen werden. PHP hat auch dieses Verhalten.
0 is not the same physical value as false. IMO ist physisch falsegenau 0im Speicher. Ich würde eher sagen, dass sie sich nach Typ unterscheiden, da sie falseboolesch sind, während sie 0ganzzahlig sind.
Beim Typzwang wird der Wert von einem Typ in einen anderen konvertiert (z. B. Zeichenfolge in Zahl, Objekt in Boolescher Wert usw.). Jeder Typ, sei es primitiv oder ein Objekt, ist ein gültiges Subjekt für Typenzwang. Um sich zu erinnern, sind Grundelemente: Zahl, Zeichenfolge, Boolescher Wert, Null, undefiniert + Symbol (in ES6 hinzugefügt).
Impliziter oder expliziter Zwang Typ-Zwang kann explizit und implizit sein.
Wenn ein Entwickler die Absicht zum Ausdruck bringt, zwischen Typen zu konvertieren, indem er den entsprechenden Code schreibt, spricht Number(value)man von explizitem Typenzwang (oder Typumwandlung).
Da JavaScript eine schwach typisierte Sprache ist, können Werte auch automatisch zwischen verschiedenen Typen konvertiert werden. Dies wird als impliziter Typenzwang bezeichnet. Es geschieht in der Regel , wenn Sie Operatoren auf Werte verschiedenen Typen gelten, wie
1 == null, 2/’5', null + new Date()oder es kann durch den umgebenden Kontext ausgelöst werden, wie mit if (value) {…}, wo Wert auf boolean wird dazu gezwungen.
Ein Operator, der keinen impliziten Typzwang auslöst ===, ist der Operator für strikte Gleichheit. Der lose Gleichheitsoperator ==hingegen führt bei Bedarf sowohl Vergleiche als auch Typzwang durch.
Impliziter Typenzwang ist ein zweischneidiges Schwert: Es ist eine große Quelle für Frustration und Fehler, aber auch ein nützlicher Mechanismus, mit dem wir weniger Code schreiben können, ohne die Lesbarkeit zu verlieren.
Drei Arten der Konvertierung Die erste Regel, die Sie kennen sollten, ist, dass es in JavaScript nur drei Arten der Konvertierung gibt:
Zweitens funktioniert die Konvertierungslogik für Grundelemente und Objekte unterschiedlich, aber sowohl Grundelemente als auch Objekte können nur auf diese drei Arten konvertiert werden.
Beginnen wir zuerst mit Primitiven.
String-Konvertierung
Um Werte explizit in einen String zu konvertieren, wenden Sie die Funktion String () an. Impliziter Zwang wird vom binären + Operator ausgelöst, wenn ein Operand eine Zeichenfolge ist:
String(123) // explicit
123 + '' // implicit
Alle primitiven Werte werden natürlich wie erwartet in Zeichenfolgen konvertiert:
String(123) // '123'
String(-12.3) // '-12.3'
String(null) // 'null'
String(undefined) // 'undefined'
String(true) // 'true'
String(false) // 'false'
Die Symbolkonvertierung ist etwas schwierig, da sie nur explizit, aber nicht implizit konvertiert werden kann.
String(Symbol('my symbol')) // 'Symbol(my symbol)'
'' + Symbol('my symbol') // TypeError is thrown
Boolesche Konvertierung
Um einen Wert explizit in einen Booleschen Wert zu konvertieren, wenden Sie die Boolean()Funktion an. Die implizite Konvertierung erfolgt im logischen Kontext oder wird von logischen Operatoren ( || && !) ausgelöst .
Boolean(2) // explicit
if (2) { ... } // implicit due to logical context
!!2 // implicit due to logical operator
2 || 'hello' // implicit due to logical operator
Hinweis: Logische Operatoren führen beispielsweise || and &&intern boolesche Konvertierungen durch, geben jedoch den Wert der ursprünglichen Operanden zurück, auch wenn sie nicht boolesch sind.
// returns number 123, instead of returning true
// 'hello' and 123 are still coerced to boolean internally to calculate the expression
let x = 'hello' && 123; // x === 123
Sobald es nur zwei mögliche Ergebnisse der Booleschen Konvertierung gibt: wahr oder falsch, ist es einfacher, sich die Liste der falschen Werte zu merken.
Boolean('') // false
Boolean(0) // false
Boolean(-0) // false
Boolean(NaN) // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(false) // false
Jeder Wert, der nicht in der Liste enthalten ist umgewandelt wird true, einschließlich object, function, Array, Date, benutzerdefinierter Typ, und so weiter. Symbole sind wahrheitsgemäße Werte. Leere Objekte und Arrays sind ebenfalls wahrheitsgemäße Werte:
Boolean({}) // true
Boolean([]) // true
Boolean(Symbol()) // true
!!Symbol() // true
Boolean(function() {}) // true
Numerische Konvertierung
Wenden Sie für eine explizite Konvertierung einfach die Number()Funktion an, genau wie Sie es mit Boolean()und getan haben String().
Die implizite Konvertierung ist schwierig, da sie in mehreren Fällen ausgelöst wird:
Vergleichsoperatoren (>, <, <=,> =)
bitweise Operatoren (| & ^ ~)
arithmetische Operatoren (- + * /%). Beachten Sie, dass binäres + keine numerische Konvertierung auslöst, wenn ein Operand eine Zeichenfolge ist.
unär + Operator
loser Gleichheitsoperator == (inkl.! =).
Beachten Sie, dass == keine numerische Konvertierung auslöst, wenn beide Operanden Zeichenfolgen sind.
Zahl ('123') // explizit + '123' // implizit 123! = '456' // implizit 4> '5' // implizit 5 / null // implizit wahr | 0 // implizit
So werden primitive Werte in Zahlen umgewandelt:
Number(null) // 0
Number(undefined) // NaN
Number(true) // 1
Number(false) // 0
Number(" 12 ") // 12
Number("-12.34") // -12.34
Number("\n") // 0
Number(" 12s ") // NaN
Number(123) // 123
Beim Typzwang wird der Wert von einem Typ in einen anderen konvertiert (z. B. Zeichenfolge in Zahl, Objekt in Boolescher Wert usw.). Jeder Typ, sei es primitiv oder ein Objekt, ist ein gültiges Subjekt für Typenzwang. Um sich zu erinnern, sind Grundelemente: Zahl, Zeichenfolge, Boolescher Wert, Null, undefiniert + Symbol (in ES6 hinzugefügt).
Typenzwang kann explizit und implizit sein.
Wenn ein Entwickler die Absicht zum Ausdruck bringt, zwischen Typen zu konvertieren, indem er den entsprechenden Code wie Number (Wert) schreibt, spricht man von explizitem Typenzwang (oder Typumwandlung).
Da JavaScript eine schwach typisierte Sprache ist, können Werte auch automatisch zwischen verschiedenen Typen konvertiert werden. Dies wird als impliziter Typenzwang bezeichnet. Dies geschieht normalerweise, wenn Sie Operatoren auf Werte unterschiedlichen Typs anwenden, z. B. 1 == null, 2 / '5', null + new Date (), oder es kann durch den umgebenden Kontext ausgelöst werden, z. B. mit if (value) {… }, wobei der Wert zum Booleschen Wert gezwungen wird.
Hier ist ein Beispiel für impliziten Zwang:
true + false
12 / "6"
"number" + 15 + 3
15 + 3 + "number"
[1] > null
"foo" + + "bar"
'true' == true
false == 'false'
null == ''
!!"false" == !!"true"
[‘x’] == ‘x’
[] + null + 1
[1,2,3] == [1,2,3]
{}+[]+{}+[1]
!+[]+[]+![]
new Date(0) - 0
new Date(0) + 0
Lesen Sie mehr: https://www.freecodecamp.org/news/js-type-coercion-explained-27ba3d9a2839/
var str = 'dude';
console.log(typeof str); // "string"
console.log(!str); // false
console.log(typeof !str); // "boolean"
Beispiel einer Variablen, die anfänglich als Zeichenfolge deklariert wird und mit dem! Operator
(true == 1) => true/(true === 1) => false.