關(guān)于 JS 類(lèi)型隱式轉(zhuǎn)換的完整總結(jié)
作者:原罪
來(lái)源:SegmentFault 思否社區(qū)
[] + {} == ?,如果你不了解其中的原理,那么就插不上話(huà),只能眼睜睜地等大佬解答了。Type
Number String Boolean Null Undefined Object Symbol
基本類(lèi)型和復(fù)合類(lèi)型兩種,除了對(duì)象,其它都是基本類(lèi)型。To Primitive
結(jié)構(gòu):toPrimitive(input, preferedType = number)
在對(duì)象的隱式轉(zhuǎn)換中,對(duì)象需要先轉(zhuǎn)成基本類(lèi)型,并按照如下順序執(zhí)行。
對(duì)象會(huì)先調(diào)用 valueOf()。如果沒(méi)有valueOf這個(gè)方法或者valueOf返回的類(lèi)型不是基本類(lèi)型,那么對(duì)象會(huì)繼續(xù)調(diào)用 toString()方法。如果沒(méi)有toString這個(gè)方法或者toString返回的類(lèi)型不是基本類(lèi)型,那么直接拋出 TypeError異常。
Uncaught TypeError: Cannot convert object to primitive value

ate的默認(rèn)preferedType=string,即在加法運(yùn)算中先執(zhí)行toString()。在 - | * | / | +x | -x 等運(yùn)算中,先執(zhí)行valueOf()數(shù)組的toString()可以等效為 join(',')其中,數(shù)組toString()時(shí),遇到null, undefined都被忽略,遇到symbol直接報(bào)錯(cuò),遇到?jīng)]有toString()的對(duì)象也報(bào)錯(cuò)。
[1, null, undefined, 2].toString() === '1,,,2';
// Uncaught TypeError: Cannot convert a Symbol value to a string
[1, Symbol('x')].toString()
// Uncaught TypeError: Cannot convert object to primitive value
[1, Object.create(null)].toString()
To Number
Number("0") === 0;
Number("") === 0;
Number(" ") === 0;
Number("\n") === 0;
Number("\t") === 0;
Number(null) === 0;
Number(false) === 0;
Number(true) === 1;
Number(undefined); // NaN
Number("x"); // NaN加減法 +-
遇到對(duì)象先執(zhí)行ToPrimitive轉(zhuǎn)換為基本類(lèi)型,然后按照基本類(lèi)型的規(guī)則處理
({}).toString() === "[object Object]"
1 + {} === "1[object Object]"
[2, 3].toString() === "2,3"
1 + [2, 3] === "12,3"
[1] + [2, 3] === "1,2,3"
function test() {}
test.toString() === "function test() {}"
10 + test === "10function test() {}"
加法過(guò)程中,遇到字符串,則會(huì)被處理為字符串拼接
1 + "1" === "11"
1 + 1 === 2
"1" + 1 === "11"
"1" + "1" === "11"
3 - 1 === 2
3 - '1' === 2
'3' - 1 === 2
// [].toString() => "" => Number(...) => 0
3 - [] === 3
// {}.toString() => "[object Object]" => Number(...) => NaN
3 - {} // NaN
加法操作時(shí),遇到非字符串的基本類(lèi)型,都會(huì)轉(zhuǎn)Number
1 + true === 2
1 + false === 1
1 + null === 1
1 + undefined // NaN
+ x 和 一元運(yùn)算 +x 是等效的(以及- x),都會(huì)強(qiáng)制轉(zhuǎn)換成Number
+ 0 === 0
- 0 === -0
1 + + "1" === 2
1 + + + + ["1"] === 2
// 負(fù)負(fù)得正
1 + - + - [1] === 2
// 負(fù)負(fù)得正
1 - + - + 1 === 2
1 - + - + - 1 === 0
1 + + [""] === 1
// ["1", "2"].toString() => "1,2" => Number(...) => NaN
1 + + ["1", "2"] // NaN
// 吃根香蕉??
("ba" + + undefined + "a").toLowerCase() === "banana"
[] + {},這樣太簡(jiǎn)單了吧?[].toString() === "";
{}.toString() === "[object Object]";
[] + {} === "[object Object]";
對(duì)象字面量{}在最前面則不代表對(duì)象
{} + [] === 0;
{ a: 2 } + [] === 0;
{}其實(shí)代表的是代碼塊,最后就變成了+ [],根據(jù)前面的原則,數(shù)組先被轉(zhuǎn)換成字符串"",接著因?yàn)?x的運(yùn)算,字符串被轉(zhuǎn)成數(shù)字0。a不是代表對(duì)象屬性,而是被當(dāng)成了標(biāo)簽(label),標(biāo)簽這東西IE6就已經(jīng)有了。所以如果我們寫(xiě)成 { a: 2, b: 3 } + [] 這樣是會(huì)報(bào)錯(cuò)的,逗號(hào)要改成分號(hào)才能通過(guò)編譯。symbol不能加減
1 + Symbol("x")報(bào)錯(cuò)如下:Uncaught TypeError: Cannot convert a Symbol value to a number
寬松相等 ==
對(duì)象與對(duì)象類(lèi)型一致,不做轉(zhuǎn)換
{} != {}
[] != {}
[] != []
對(duì)象與基本類(lèi)型,對(duì)象先執(zhí)行ToPrimitive轉(zhuǎn)換為基本類(lèi)型
// 小心代碼塊
"[object Object]" == {}
[] == ""
[1] == "1"
[1,2] == "1,2"
數(shù)字與字符串類(lèi)型對(duì)比時(shí),字符串總是轉(zhuǎn)換成數(shù)字
"2" == 2
[] == 0
[1] == 1
// [1,2].toString() => "1,2" => Number(...) => NaN
[1,2] != 1
布爾值先轉(zhuǎn)換成數(shù)字,再按數(shù)字規(guī)則操作
// [] => "" => Number(...) => 0
// false => 0
[] == false
// [1] => "1" => 1
// true => 1
[1] == true
// [1,2] => "1,2" => NaN
// true => 1
[1,2] != true
"0" == false
"" == false
null、undefined、symbol
null == undefined 是一個(gè)特例。null == null
undefined == undefined
null == undefined
null != 0
null != false
undefined != 0
undefined != false
Symbol('x') != Symbol('x')
對(duì)比 < >
對(duì)象總是先執(zhí)行ToPrimitive為基本類(lèi)型
[] < [] // false
[] <= {} // true
{} < {} // false
{} <= {} // true
任何一邊出現(xiàn)非字符串的值,則一律轉(zhuǎn)換成數(shù)字做對(duì)比
// ["06"] => "06" => 6
["06"] < 2 // false
["06"] < "2" // true
["06"] > 2 // true
5 > null // true
-1 < null // true
0 <= null // true
0 <= false // true
0 < false // false
// undefined => Number(...) => NaN
5 > undefined // false

評(píng)論
圖片
表情
