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