关于 JavaScript 那些迷之神奇的 "bug"?

727 阅读3分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

学习贵在坚持, 笔记是灵魂, 温故而知新, 时不时翻一翻, 回顾一下知识点, 加深记忆, 事半功倍!

前文我们学习了基本的 数据结构: 对象和数组

今天继续来学习 JavaScript 之 那些迷之神奇的特殊 "bug". eg: [] == ![] --> true???

如封面图所示, 这些运算等表达式 不看答案你能一下说出来正确答案吗?

1. 先来看看最最基本的数字 Number

上图说话:

js-999999

因为 JavaScript 中的 Number.MAX_SAFE_INTEGER, 大于这个安全数的整数巨大多数都无法被精确表示.

js-number

2. JavaScript 中的 各种等号: = == ===

这一个等号=, 就是赋值操作不用说了; ==为宽松相等运算, 先转换类型再比较; ===为严格判断 先判断类型,如果不是同一类型直接返回 false.

所以用===才是我们要用的相等判断运算符, 应该避免使用 ==, 因为你看下面:

1 == '1' // true
1 === '1' // false

先来看一下 JavaScript 中的这个==,我们称之为 抽象相等比较法. 比较两个值相对于 === 宽松一些, 也会进行隐式类型转换. 比如下面的示例:

[] == []
[] == ![]

你能猜到上面两行是什么结果么?

第一个返回 false, 大家应该都能理解: 两个数组并不是同一个对象, 所以不相等. 是第二行就是迷之神奇了, 它返回 **true**你敢信吗? 那这样就是 某某 等于 非某某...

空数组是对象, 是幻真的所以 ![] 为 false. 而使用== 宽松相等运算符会将 []false进行类型转换成数值再进行比较, 但是它们实际上都不是数值类型.

这里的比较 == 的类型转换逻辑: 空数组 被强制转换成空字符串, 空字符串再被强制转换成 0. 而 false 也被转换成 0, 这样就相等了..

2. 对象 和数组的算术运算 +

[] + [] // ''

[] + {} // "[object Object]"

{} + {} // "[object Object][object Object]"

按说 两值相加得出无意义的值时 为 NaN, 这里的表达式应该都是 NaN...

这里进行算术运算的都不是数值类型, +就会把他们拼接起来. 首先就是把操作数转换成字符串:

  • 数组用 Array.prototype.toString()方法转换成空字符串,
  • 然鹅 对象却被 Object.prototype.toString()方法渲染成了 "[object Object]".

就这样 就拼接成了这些奇怪的字符串

你以为这样就结束了吗? 来看看下面这个

{} + []

猜猜看这个表达式的结果是什么呢? 没错 就是你猜错了, 它的结果是 0

上面说的 [] 在前面, 两者就会进行转换,

但如果{}(空对象)在前面,而 [](空数组)在后面时,前面(左边)那个运算元({})会被认为是区块语句而不是对象字面量。

所以表达式 {} + [] 就相当于 +[], 也就是相当于强制求出数字值的 Number([])运算,相当于 Number("") 运算,最后得出的是数字 0

还有更多迷之怪异的现象, 这里就不一一列举了, 感兴趣的同学可根据封面图自行探索哟^^

更多阅读请查收:

【数据结构】数据结构-对象和数组(二)数组 Array【数据结构】数据结构-对象和数组(一)对象 Object【数据结构】深入了解 JSON

【Node.js】文件系统服务器-模拟接口

【Node.js】文件系统模块【Node.js】HTTP 模块

【Node.js】效率工具-nvm & nrm 等

【Node.js】包管理工具 npm & yarn 的使用

【Node.js】搭建自动化开发环境-基本介绍

【Node.js】安装&文档【工具准备】【开工】【详细步骤(四)】【模块处理工具(五)】【模块化编程的理解】

【Github】多人协作(二)【Github】基本使用(一)

【Git】代码版本控制-git 初识&基本操作(一)【Git】进阶(二)

跟上节奏, 一步一步! 下文更新预告:

接下来会继续详细学习 JavaScript 的相关方法, 冲鸭!! xdm

学习用到的效率工具, 提高开发效率, 为我们的开发提效赋能!

跟上前进的步伐, 加油!! go~~