來(lái)源:一篇文章搞定JS類(lèi)型轉(zhuǎn)換
作者:老姚
為啥要說(shuō)這個(gè)東西歹篓?
一道面試題就給我去說(shuō)它的動(dòng)機(jī)萎战。
題如下:
var bool = new Boolean(false);
if (bool) {
alert('true');
} else {
alert('false');
}
運(yùn)行結(jié)果是true8廊荨!蚂维!
其實(shí)啥類(lèi)型轉(zhuǎn)換啊戳粒,操作符優(yōu)先級(jí)啊,這些東西都是最最基本的虫啥。
犀牛書(shū)上有詳細(xì)的介紹蔚约。但我很少去翻犀牛書(shū)的前5章。涂籽。苹祟。
比如說(shuō)優(yōu)先級(jí)那塊兒,很多書(shū)都教育我們评雌,“不用去背誦優(yōu)先級(jí)順序树枫,不確定的話,加括號(hào)就行了景东∩扒幔“
平常我們寫(xiě)代碼時(shí)也確實(shí)這么做的。
但現(xiàn)實(shí)是啥呢斤吐?面試時(shí)會(huì)出這種題搔涝,讓你來(lái)做厨喂。。庄呈。
真不知道這種題的意義是啥蜕煌。。抒痒。
抱怨到此為止幌绍,本文嘗試來(lái)解決類(lèi)型轉(zhuǎn)換問(wèn)題,爭(zhēng)取把《JS權(quán)威指南》49頁(yè)那個(gè)表背下來(lái)故响。
都有哪些東西是假值?
共6個(gè):
0或+0颁独、-0彩届,NaN
""
false
undefined
null
上面的順序是按照基本類(lèi)型來(lái)排列的。
除此之外的一律不是J木啤樟蠕!哪怕是如下形式:
Infinity
'0'、'false'靠柑、" "(空格字符)
任何引用類(lèi)型:[],{},function(){}
if (a && b)的正確理解方式是:a && b進(jìn)行表達(dá)式求值后寨辩,然后再轉(zhuǎn)換為Boolean類(lèi)型。
&&是種短路語(yǔ)法歼冰,求值后不一定是個(gè)Boolean類(lèi)型靡狞,更不是兩邊轉(zhuǎn)化布爾值再運(yùn)算。
比如 2&&3 的結(jié)果是3隔嫡,不是true甸怕。
所以if(a && b),我們平常理解的那種腮恩,"如果a和b同時(shí)為真的話"梢杭,是一種錯(cuò)誤的描述方式。
其他基本類(lèi)型轉(zhuǎn)化為字符串秸滴,基本和預(yù)期的一樣:
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"
其他基本類(lèi)型轉(zhuǎn)化為數(shù)字武契,需要特殊記憶:
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
其中null,空字符是0荡含,undefined是NaN咒唆。
以上,基本類(lèi)型轉(zhuǎn)換都說(shuō)明白了内颗。
下面來(lái)看看引用類(lèi)型轉(zhuǎn)換為基本類(lèi)型钧排。
引用類(lèi)型轉(zhuǎn)換為布爾,始終為true
引用類(lèi)型轉(zhuǎn)換為字符串
1.優(yōu)先調(diào)用toString方法(如果有)均澳,看其返回結(jié)果是否是原始類(lèi)型恨溜,如果是符衔,轉(zhuǎn)化為字符串,返回糟袁。
2.否則判族,調(diào)用valueOf方法(如果有),看其返回結(jié)果是否是原始類(lèi)型项戴,如果是形帮,轉(zhuǎn)化為字符串,返回周叮。
3.其他報(bào)錯(cuò)辩撑。
引用類(lèi)型轉(zhuǎn)化為數(shù)字
1.優(yōu)先調(diào)用valueOf方法(如果有),看其返回結(jié)果是否是基本類(lèi)型仿耽,如果是合冀,轉(zhuǎn)化為數(shù)字,返回项贺。
2.否則君躺,調(diào)用toString方法(如果有),看其返回結(jié)果是否是基本類(lèi)型开缎,如果是棕叫,轉(zhuǎn)化為數(shù)字,返回奕删。
3.其他報(bào)錯(cuò)俺泣。
首先我們看看常見(jiàn)引用類(lèi)型toString和valueOf返回什么?
var a = {};
console.dir(a.toString()); // "[object Object]"
console.dir(a.valueOf()); // 對(duì)象本身
var b = [1, 2, 3];
console.dir(b.toString()); // "1,2,3"
console.dir(b.valueOf()); // 對(duì)象本身
var c = [[1],[2]];
console.dir(c.toString()); // "1,2"
console.dir(c.valueOf()); // 對(duì)象本身
var d = function() {return 2};
console.dir(d.toString()); // "function() {return 2}"
console.dir(d.valueOf()); // 對(duì)象本身
因此對(duì)應(yīng)的轉(zhuǎn)換為字符串和數(shù)字的情形是:
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
再來(lái)個(gè)報(bào)錯(cuò)的情形:
var a = {};
a.toString = function() {return {};}
console.log("" + a); // 報(bào)錯(cuò)
console.log(+a) // 報(bào)錯(cuò)
以上類(lèi)型轉(zhuǎn)換規(guī)律基本說(shuō)完急侥。
最后來(lái)說(shuō)一下萬(wàn)惡的“==”
面試題如下:
var a = false;
var b = undefined;
if (a == b) {
alert('true');
} else {
alert('false');
}
本以為會(huì)彈出true的砌滞。天那!為啥是false?
哈哈。坏怪。贝润。
雙等號(hào),如果兩邊類(lèi)型不同铝宵,會(huì)有隱式轉(zhuǎn)換發(fā)生打掘。犀牛書(shū)75頁(yè)總結(jié)如下:
1,null和undefined鹏秋,相等尊蚁。
2,數(shù)字和字符串侣夷,轉(zhuǎn)化為數(shù)字再比較横朋。
3,如果有true或false百拓,轉(zhuǎn)換為1或0琴锭,再比較晰甚。
4,如果有引用類(lèi)型决帖,優(yōu)先調(diào)用valueOf厕九。
5,其余都不相等地回。
因此有:
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之所以為true根據(jù)第3條扁远。
"" == false之所以為true根據(jù)第3條,變成了"" == 0,再根據(jù)第2條刻像。
第4條再來(lái)一個(gè)例子:
console.log([[2]] == '2')
其上結(jié)果為true畅买,原因如下:
[[2]]的valueOf是對(duì)象本身,不是基本類(lèi)型细睡。
嘗試調(diào)用toString的結(jié)果是'2'皮获。
因此變成了'2'和數(shù)字2的比較。根據(jù)第2條纹冤,相等。WTF!!
最后說(shuō)句购公,使用"==="就沒(méi)有這些問(wèn)題了萌京。
本文完。