image.png

这毫无道理。

一个数组怎么可能不是一个数组呢?
image.png

[] 是真值,而 ![] 应该是 false

那么 [] 怎么可能等于 false 呢?

而且这种情况似乎并不发生在其他类型上,比如字符串和数字:

image.png

JavaScript的数组是不是坏了?

这里发生了什么

把所有的责任都推给危险的 == 运算符。

这只是我们总是告诉JavaScript新手永远不要使用它(真的永远不要)的又一个例子。

尤其是如果他们之前一直在使用像C#这样固执且严格的语言编程。

乍一看,== 似乎没有任何问题:

image.png

image.png

但现在看看这里发生了什么:

image.png

但看看在JavaScript中发生了什么:

image.png

JavaScript自动将字符串转换成了数字!

这是人们对JavaScript的诸多不满之一,这也是TypeScript出现的原因。

image.png

那么你认为在 [] == ![] 的背后,真正发生了什么?

首先,在JavaScript中空数组是真值,所以 ! 作用于它使其变成 false

image.png

我们突然发现自己在比较一个 数组 和一个 布尔值。显然不会有好结果。

正如我们现在所知,JS并不在意,所以它就继续进行 — 这次将 布尔值 转换为等价的数字

image.png

接下来,由于一些你永远不需要知道的垃圾规则,[] 变成了...一个空字符串?

image.png

最后它将 "" 转换成...一个数字:

image.png

那么,避免这种荒谬情况的解决方案是什么?

始终使用严格相等运算符 ===

image.png

没有任何可以想象的场景是 == 可以使用而 === 不能使用的

现在使用 ===,VS Code编辑器突然活跃起来,阻止我们做类似这样的事情:

image.png

但之前它是沉睡的:

image.png

[] == [] 呢?

好的,这说得通,但那么什么可以解释这个:

image.png

肯定不能怪 == 了。它们有相同的类型,不是吗?

是的,它们确实有。

只是JavaScript通过引用比较数组。而不是通过值。

它们可能有完全相同的值,但只要它们不指向内存中的同一个对象,在 ===== 看来它们就永远不会相等。

image.png

对于对象来说一般也是这样:

image.png

当然,对于我们的核心原始值 — 字符串、数字和布尔值 — 情况并非如此

image.png

那么,当你想按元素值比较数组时该怎么办?

如果是已排序的,你可以使用 JSON.stringify()

image.png

否则,你可以使用更通用的 lengthevery() 组合:

image.png

最后的思考

== 只是JavaScript松散性导致它做出在现实世界中毫无意义的事情的一个例子。

道德教训:始终使用严格相等,使用TypeScript,并优先使用现代特性。

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。


王大冶
68k 声望104.9k 粉丝