Heim  >  Artikel  >  Web-Frontend  >  Lassen Sie uns die Fallstricke der JS-Typkonvertierung besprechen

Lassen Sie uns die Fallstricke der JS-Typkonvertierung besprechen

阿神
阿神Original
2017-01-23 14:18:041215Durchsuche

Warum sagst du das?
Eine Frage im Vorstellungsgespräch gab mir die Motivation, es zu sagen.
Die Frage lautet wie folgt:

var bool = new Boolean(false);
if (bool) {
    alert('true');
} else {
    alert('false');
}

Das Laufergebnis stimmt! ! !
Eigentlich sind Typkonvertierung und Operatorpriorität die grundlegendsten Dinge.
Eine ausführliche Einführung gibt es im Rhino-Buch. Aber ich habe die ersten fünf Kapitel des Rhino-Buches selten gelesen. . .
Zum Beispiel lehren uns viele Bücher in Bezug auf Prioritäten: „Es ist nicht nötig, sich die Prioritätsreihenfolge zu merken. Wenn Sie sich nicht sicher sind, fügen Sie einfach Klammern hinzu.“
Normalerweise machen wir das beim Schreiben von Code.
Aber was ist die Realität? Diese Art von Frage wird im Vorstellungsgespräch gestellt und Sie werden gebeten, diese zu beantworten. . .
Ich weiß wirklich nicht, was diese Frage bedeutet. . .
Die Beschwerden hören hier auf. Dieser Artikel versucht, das Typkonvertierungsproblem zu lösen und sich die Tabelle auf Seite 49 des „JS Definitive Guide“ zu merken.
Was sind die falschen Werte?
Insgesamt 6:

0或+0、-0,NaN
""
false
undefined
null

Die obige Reihenfolge ist nach den Grundtypen geordnet.
Nichts anderes! ! Auch wenn es in der folgenden Form vorliegt:

Infinity
'0'、'false'、" "(空格字符)
任何引用类型:[],{},function(){}

Der richtige Weg, if (a && b) zu verstehen, ist: a && b wertet den Ausdruck aus und wandelt ihn dann in den Booleschen Wert um Typ.
&& ist eine Kurzschlusssyntax. Nach der Auswertung ist es nicht unbedingt ein boolescher Typ und wird auch nicht auf beiden Seiten in boolesche Werte konvertiert und dann verarbeitet.
Zum Beispiel ist das Ergebnis von 2&&3 3, was nicht wahr ist.
Wenn also (a && b), was wir normalerweise verstehen, „wenn a und b gleichzeitig wahr sind“, ist eine falsche Art, es zu beschreiben.
Andere Grundtypen werden in Zeichenfolgen konvertiert , was im Grunde das Gleiche ist wie erwartet:

console.log("" + null);      // "null"
console.log("" + undefined); // "undefined"
console.log("" + false);     // "false"
console.log("" + true);      // "true"
console.log("" + 0);         // "0"
console.log("" + NaN);       // "NaN"
console.log("" + Infinity);  // "Infinity"

Andere Grundtypen werden in Zahlen konvertiert , was erforderlich ist Spezialspeicher:

console.log(+null);          // 0
console.log(+undefined);     // NaN
console.log(+false);         // 0
console.log(+true);          // 1
console.log(+"");            // 0
console.log(+'1');           // 1
console.log(+'1x');          // NaN

Wobei null das leere Zeichen 0 ist und undefiniert NaN ist.
Oben wird die grundlegende Typkonvertierung klar erläutert.

Sehen wir uns die Konvertierung von Referenztypen in Basistypen an.
Referenztyp in booleschen Wert konvertiert, immer wahr
Referenztyp in Zeichenfolge konvertiert

1.优先调用toString方法(如果有),看其返回结果是否是原始类型,如果是,转化为字符串,返回。
2.否则,调用valueOf方法(如果有),看其返回结果是否是原始类型,如果是,转化为字符串,返回。
3.其他报错。

Referenztyp in Zahl konvertiert

1.优先调用valueOf方法(如果有),看其返回结果是否是基本类型,如果是,转化为数字,返回。
2.否则,调用toString方法(如果有),看其返回结果是否是基本类型,如果是,转化为数字,返回。
3.其他报错。

Schauen wir uns zunächst an, was die gemeinsamen Referenztypen toString und valueOf zurückgeben.

var a = {};
console.dir(a.toString());   // "[object Object]"
console.dir(a.valueOf());    // 对象本身
 
var b = [1, 2, 3];
console.dir(b.toString());   // "1,2,3"
console.dir(b.valueOf());    // 对象本身
 
var c = [[1],[2]];
console.dir(c.toString());   // "1,2"
console.dir(c.valueOf());    // 对象本身
 
var d = function() {return 2};
console.dir(d.toString());   // "function() {return 2}"
console.dir(d.valueOf());    // 对象本身

Die entsprechende Konvertierung in Zeichenfolgen und Zahlen lautet also:

var a = {};
console.dir(a + "");         // "[object Object]"
console.dir(+a);             // NaN
 
var b = [1, 2, 3];
console.dir(b + "");         // "1,2,3"
console.dir(+b);             // NaN
 
var c = [[1],[2]];
console.dir(c + "");         // "1,2"
console.dir(+c);             // NaN
 
var d = function() {return 2};
console.dir(d + "");         // "function () {return 2}"
console.dir(+d);             // NaN

Eine weitere Fehlersituation:

var a = {};
a.toString = function() {return {};}
console.log("" + a);         // 报错
console.log(+a)              // 报错

Die oben genannten Typkonvertierungsregeln sind im Grunde genommen abgeschlossen.

Lassen Sie uns zum Schluss über das Böse sprechen „==“
Die Interviewfragen lauten wie folgt:

var a = false;
var b = undefined;
if (a == b) {
    alert('true');
} else {
    alert('false');
}

Ich dachte, dass „Wahr“ auftauchen würde. Oh mein Gott! Warum ist das falsch?
Haha. . .
Doppeltes Gleichheitszeichen. Wenn die Typen auf beiden Seiten unterschiedlich sind, erfolgt eine implizite Konvertierung. Rhino-Buchseite 75 fasst es wie folgt zusammen:

1,null和undefined,相等。
2,数字和字符串,转化为数字再比较。
3,如果有true或false,转换为1或0,再比较。
4,如果有引用类型,优先调用valueOf。
5,其余都不相等。

Daher gilt:

console.log(undefined == false); // false
console.log(null == false);      // false
console.log(0 == false);         // true
console.log(NaN == false);       // false
console.log("" == false);        // true

0 == false, was gemäß Klausel 3 wahr ist.
Der Grund, warum „“ == false gemäß Artikel 3 wahr ist, wird zu „“ == 0 und dann gemäß Artikel 2.
Ein weiteres Beispiel in Artikel 4:

console.log([[2]] == 2)

Das obige Ergebnis ist aus folgenden Gründen wahr:
[[2]]'s valueOf ist das Objekt selbst, nicht der Basistyp.
Das Ergebnis des Versuchs, toString aufzurufen, ist „2“.
So entsteht ein Vergleich zwischen „2“ und der Zahl 2. Gemäß Artikel 2 gleich. WTF!!
Schließlich werden diese Probleme durch die Verwendung von „===" beseitigt.
Dieser Artikel ist fertig.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn