本文同步本人掘金平台的原创翻译:https://juejin.cn/post/6844903904816136206
TLDR:强迫自己使用三重等号(===)
我无意在Reddit上找到了这个JavaScript meme,它是我见过最好的抽象。
你可以通过运行开发者工具来运行(图中)的每行代码来验证此关系的准确性。结果并不令人惊讶,但仍然令人失望。
当然,这个小实验触发了我的兴趣…
这是怎么发生的?
凭借经验,我学会了接受JavaScript这滑稽的一面,同时感受它的松散。尽管如此,这个事件的细节仍然让我感到困惑。
正如Kyle Simpson所说…
“不管怎么说,我认为任何人都不会真正了解JS”
当这些案例出现时,最好查阅源代码–构建JavaScript的官方ECMAScript规范。
有了这个规范,让我们深刻理解这里发生了什么。
板块1 – 引入强制
如果你在开发者控制台上运行0 == “0”,为什么它返回true?
0是一个数字,然后”0″是一个字符串,它们永远不应该相同的!大多数编程语言都遵守它。例如,Java中的0 == “0”,会返回下面这个:
error: incomparable types: int and String 复制代码
这很有道理。如果要比较Java中的int和String,必须先把它们转换为相同的类型。
但这是JavaScript,你们呀!
当你通过==比较两个值时,其中一个值可能受到强制转换。
强制 – 自动将值从一种类型转换为另一种类型。
这里的自动是关键词。JavaScript不是在显式转换你的类型,而是在幕后帮你完成。
如果你有目的地利用它,这很方便,但如果你不知道它的含义,则可能有害。
这是关于它的官方ECMAScript语言规范。 我会解释相关部分:
If x is number and y is String, return x == ToNumber(y)
译:如果 x 是数字类型,y 是字符串类型,将 y 转换成数字类型与 x 作比较后返回
所以我们的例子0 == “0”:
因为 0 是一个数字类型,”0″ 是一个字符串类型,则返回 0 == ToNumber(“0”)
我们的字符串”0″已经被秘密转换成数字0,现在我们有一个匹配了!
0 == "0" // true // The second 0 became a number! // so 0 equals 0 is true.... 复制代码
奇怪吧?好好习惯它,我们接着说~
板块2 – 数组也被强制
这种强制不仅仅限制于字符串,数字或布尔值等基本数据类型。这是我们的下一个比较:
0 == [] // true // What happened...? 复制代码
再次被强制了!我将解释规范的相关部分:
If x is String or Number and y is Object, return x == ToPrimitive(y)
译:如果 x 是字符串或数字类型,然后 y 是对象类型,将 y 转换为基本数据类型与 x 作比较后返回
这里有三件事:
1.是的,数组是对象
抱歉,刷新了你的认知。
2.空数组变成空字符串
再次根据规范,JS首先寻找一个对象的toString方法来强制转换它。
在数组的情况下,toString连接其所有元素并将它们作为字符串返回。
[1, 2, 3].toString() // "1,2,3" [hello, world].toString() // "hello,world" 复制代码
因为我们的数组是空的,我们没内容去拼接!所以…
[].toString() // "" 复制代码
规范中的ToPrimitive将空数组转换成空字符串。相关的参考在这里和这里,方便你查阅(或解决疑惑)。
3.空字符串然后变成0
你不能把这些东西搞定。现在我们已经将数组强制变成””,我们又回到了第一个算法(规范)…
If x is Number and y is String, return x == ToNumber(y)
所以0==””
Since 0 is Number and “” is String, return 0 == ToNumber(“”)
ToNumber(“”)返回 0 。
因此,再一次是0==0…
板块3 – 快速回顾
这是正确的0 == "0" // true 复制代码
因为被强制转换成这个0 == ToNumber(“0”)。
这也是正确的0 == [] // true 复制代码
因为强制转换执行两次:
- ToPrimitive([])转换为空字符串
- 然后ToNumber(“”)转换为 0 。
所以,告诉我…根据上面的规则,下面将返回什么?
"0" == [] 复制代码
板块4 – FALSE!
FALSE! 正确。
如果你明白规则,这部分是有意义的。
下面是我们的比较:
"0" == [] // false 复制代码
再次参考规范:
If x is String or Number and y is Object, return x == ToPrimitive(y)
那就意味着…
Since “0” is String and [] is Object, return x == ToPrimitive([])
"0" == "" 复制代码
“0”和””都是字符串类型,所以JavaScript不需要再强制转换了。这就是为什么得到结果为false的原因。
总结
使用三重等号(===),然后晚上睡个好觉。
0 === "0" // false 0 === [] // false "0" === [] // false 复制代码
它完全避免强制转换,所以我猜它也更有效率!
但是(===对于)性能的提升几乎毫无意义。真正的胜利是你在代码中增加的信心,使得额外的击打键盘完全值得。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容