為什么在JavaScript中 [] == ![] 返回 TRUE?
圖片
這毫無道理。
一個(gè)數(shù)組怎么可能不是一個(gè)數(shù)組呢?
圖片
[] 是真值,而 ![] 應(yīng)該是 false。
那么 [] 怎么可能等于 false 呢?
而且這種情況似乎并不發(fā)生在其他類型上,比如字符串和數(shù)字:
圖片
JavaScript的數(shù)組是不是壞了?
這里發(fā)生了什么
把所有的責(zé)任都推給危險(xiǎn)的 == 運(yùn)算符。
這只是我們總是告訴JavaScript新手永遠(yuǎn)不要使用它(真的永遠(yuǎn)不要)的又一個(gè)例子。
尤其是如果他們之前一直在使用像C#這樣固執(zhí)且嚴(yán)格的語言編程。
乍一看,== 似乎沒有任何問題:
圖片
圖片
但現(xiàn)在看看這里發(fā)生了什么:
圖片
但看看在JavaScript中發(fā)生了什么:
圖片
JavaScript自動(dòng)將字符串轉(zhuǎn)換成了數(shù)字!
這是人們對JavaScript的諸多不滿之一,這也是TypeScript出現(xiàn)的原因。
圖片
那么你認(rèn)為在 [] == ![] 的背后,真正發(fā)生了什么?
首先,在JavaScript中空數(shù)組是真值,所以 ! 作用于它使其變成 false
圖片
我們突然發(fā)現(xiàn)自己在比較一個(gè) 數(shù)組 和一個(gè) 布爾值。顯然不會(huì)有好結(jié)果。
正如我們現(xiàn)在所知,JS并不在意,所以它就繼續(xù)進(jìn)行 — 這次將 布爾值 轉(zhuǎn)換為等價(jià)的數(shù)字
圖片
接下來,由于一些你永遠(yuǎn)不需要知道的垃圾規(guī)則,[] 變成了...一個(gè)空字符串?
圖片
最后它將 "" 轉(zhuǎn)換成...一個(gè)數(shù)字:
圖片
那么,避免這種荒謬情況的解決方案是什么?
始終使用嚴(yán)格相等運(yùn)算符 ===。
圖片
沒有任何可以想象的場景是 == 可以使用而 === 不能使用的
現(xiàn)在使用 ===,VS Code編輯器突然活躍起來,阻止我們做類似這樣的事情:
圖片
但之前它是沉睡的:
圖片
但 [] == [] 呢?
好的,這說得通,但那么什么可以解釋這個(gè):
圖片
肯定不能怪 == 了。它們有相同的類型,不是嗎?
是的,它們確實(shí)有。
只是JavaScript通過引用比較數(shù)組。而不是通過值。
它們可能有完全相同的值,但只要它們不指向內(nèi)存中的同一個(gè)對象,在 == 和 === 看來它們就永遠(yuǎn)不會(huì)相等。
圖片
對于對象來說一般也是這樣:
圖片
當(dāng)然,對于我們的核心原始值 — 字符串、數(shù)字和布爾值 — 情況并非如此
圖片
那么,當(dāng)你想按元素值比較數(shù)組時(shí)該怎么辦?
如果是已排序的,你可以使用 JSON.stringify():
圖片
否則,你可以使用更通用的 length 和 every() 組合:
圖片
最后的思考
== 只是JavaScript松散性導(dǎo)致它做出在現(xiàn)實(shí)世界中毫無意義的事情的一個(gè)例子。
道德教訓(xùn):始終使用嚴(yán)格相等,使用TypeScript,并優(yōu)先使用現(xiàn)代特性。