[]== ![] 答案為什么會(huì)是True?
解析1
- [] == !true // ! 操作符的優(yōu)先級(jí)高于==,所以先執(zhí)行!操作;“!”是取反操作,空數(shù)組是對象,對象為真,取反之后就為false了
- [] == false // !true 得到的是 false
- [] == 0 // 比較規(guī)則1:如果值為true或false,則轉(zhuǎn)成1或0來繼續(xù)比較
- [] == 0 // 執(zhí)行左側(cè)的 [] 的 valueOf 方法,而 [] 是對象,所以 [].valueOf() 返回本身 []
- "" == 0 // 執(zhí)行左側(cè)的 [] 的 toString 方法,[].toString() 返回 ""
- 0 == 0 // 比較規(guī)則2:如果一個(gè)值是數(shù)字,一個(gè)值是字符串,則把字符串轉(zhuǎn)換為數(shù)字,再進(jìn)行比較,"" 轉(zhuǎn)成數(shù)字是 0。
- 最終是執(zhí)行 0 == 0 ,結(jié)果為 true 。
解析2
首先,“!”是取反操作,空數(shù)組是對象,對象為真,取反之后就為false了。
然后,相等運(yùn)算符的比較有指定的規(guī)則,具體請參閱諸如《JavaScript權(quán)威指南》或者《JavaScript高級(jí)程序設(shè)計(jì)》等書目。其中有兩條指出:
- 如果其中一個(gè)值是true,則將其轉(zhuǎn)換為1再進(jìn)行比較。如果其中一個(gè)值是false,則將其轉(zhuǎn)換為0再進(jìn)行比較。
- 如果一個(gè)值是對象,另一個(gè)值是數(shù)字或字符串,則將對象轉(zhuǎn)換為原始值再進(jìn)行比較。對象通過toString()方法或valueOf()方法轉(zhuǎn)換為原始值。JavaScript語言核心的內(nèi)置類首先嘗試使用valueOf(),在嘗試使用toString(),除了日期類,日期類只使用toString()方法,那些不是JavaScript語言核心中的對象則通過各自實(shí)現(xiàn)中定義的方法轉(zhuǎn)換為原始值。
有了以上兩條作為基礎(chǔ),我們再來看問題。
控制臺(tái)指出等號(hào)右邊為布爾值,由第一條可知,它將轉(zhuǎn)換為數(shù)字0,也就是數(shù)字類型。
現(xiàn)在變成了空數(shù)組和數(shù)字 0 的比較。由第二條可知,空數(shù)組會(huì)首先調(diào)用valueOf()方法,但是這里需要注意的是:數(shù)組、函數(shù)和正則表達(dá)式調(diào)用valueOf()方法后,只返回對象本身。
所以,繼續(xù)調(diào)用toString()方法,空數(shù)組調(diào)用toString()后,眾所周知會(huì)返回 0 ;于是兩邊相同。也就是為什么有了后面所示結(jié)果的原因了。"" == ![] //true1 == ![] // false0 == ![] // true可以一句話概括:任意值與布爾值之間的比較都是數(shù)字0和1之間的比較。
"" == ![] //true
1 == ![] // false
0 == ![] // true
可以一句話概括:任意值與布爾值之間的比較都是數(shù)字0和1之間的比較。
規(guī)范
首先,== 的定義是:
GetValue 會(huì)獲取一個(gè)子表達(dá)式的值(消除掉左值引用),在表達(dá)式 [] == ![] 中,[] 的結(jié)果就是一個(gè)空數(shù)組的引用,而 ![] 就有意思了,它會(huì)按照 11.4.9 和 9.2 節(jié)的要求得到 false。
在這段算法里,和「[] == ![]」匹配的是條件 7,所以會(huì)遞歸地調(diào)用「[] == ToNumber(false)」進(jìn)行比較。在 9.3 節(jié)中定義了 ToNumber 原語,ToNumber(false) 等于 0,于是比較變?yōu)椤竅] == 0」。在此處因?yàn)?[] 是對象,比較過程走分支 9,依「ToPrimitive([]) == 0」比較。ToPrimitive 默認(rèn)是調(diào)用 toString 方法的(依 8.2.8),于是 ToPrimitice([]) 等于空字符串。結(jié)果,[] == ![] 的比較最后落到了 ''==false 上,按照 11.9.3 中的定義會(huì)依分支 5 比較 「ToNumber('')==0」,ToNumber('') 依 9.3.1 等于 0,所以結(jié)果為 true。
?文章出自:??前端餐廳??,如有轉(zhuǎn)載本文請聯(lián)系前端餐廳今日頭條號(hào)。
github:??https://github.com/zuopf769??