== 与 === 的区别及隐式转换
1. 核心区别
==:会进行隐式类型转换 (Coercion),尝试将两个值转换为相同类型后再比较。===:如果类型不同,直接返回false。如果类型相同,再比较值。永远推荐使用===。
2. 隐式类型转换规则 (面试考点)
(1) null 和 undefined
(2) 字符串 vs 数字
如果有一个是数字,另一个也会被转换为数字。
(3) 布尔值 vs 其他类型
如果有布尔值,布尔值先转为数字 (true -> 1, false -> 0)。
(4) 对象 vs 原始值
如果有一个是对象,会先将对象转换为原始值。
转换顺序:
- 调用
obj[Symbol.toPrimitive](hint) - 调用
obj.valueOf() - 调用
obj.toString()
3. 经典面试题解析
(1) [] == ![] 为什么是 true?
步骤拆解:
![]优先级更高,空数组转 Boolean 为 true,取反为 false。- 比较变为:
[] == false。 - 有一方是 Boolean,转为数字:
false->0。 - 比较变为:
[] == 0。 - 有一方是对象,
[]转换为原始值:[].valueOf()->[](非原始值),继续[].toString()->""(空字符串)。 - 比较变为:
"" == 0。 - 有一方是字符串,转为数字:
Number("")->0。 - 最终:
0 === 0-> false (等等,这里逻辑错了?)
❌ 修正逻辑:
![]->false。[] == false。- Boolean 转 Number:
[] == 0。 - Object 转 Primitive:
"" == 0。 - String 转 Number:
0 === 0-> true。
(2) obj.valueOf 和 toString 哪个先执行?
如果是 == 比较,默认 hint 是 'default' (表现像 'number'),优先调用 valueOf。如果 valueOf 返回对象,再调用 toString。
Date 对象特殊,默认 hint 是 'string',优先 toString。
4. 特殊值比较
NaN:与任何值都不相等,包括自己。+0vs-0:
5. 面试加分项:Object.is()
Object.is(val1, val2) 与 === 基本一致,只有两个区别:
+0不等于-0。NaN等于NaN。

