加法运算
核心规则
- 如果任意操作数是字符串:执行字符串连接。
- 如果所有操作数都是非字符串:尝试转换为数字后相加。
- 对象/数组的转换:优先调用
valueOf()
,若无有效原始值则调用toString()
总结表
操作数组合 | 转换规则 | 结果示例 |
---|---|---|
字符串 + 任意类型 | 全转字符串后连接 | "5" + 1 → "51" |
数字 + 布尔/null | 转数字后相加 | 10 + true → 11 |
数字 + undefined | undefined → NaN | 10 + undefined → NaN |
对象/数组 + 非对象 | 对象转原始值再运算 | [] + 1 → "1" |
多个操作数 | 从左到右逐步转换 | 1 + 2 + "3" → "33" |
示例
// 数字 + 非字符串 → 数字相加
10 + true; // 11(true → 1)
10 + null; // 10(null → 0)
10 + undefined; // NaN(undefined → NaN)
// 对象/数组的转换
[] + 1; // "1"([] → "" → 字符串连接)
[1, 2] + 3; // "1,23"(数组转字符串 "1,2")
{} + []; // 0({} 被解析为空代码块,实际计算 +[] → 0)
({} + []); // "[object Object]"(明确对象运算)
// 布尔值参与运算
true + false; // 1(布尔值转数字)
true + "!"; // "true!"(布尔值转字符串)
// null 和 undefined
null + null; // 0(转数字)
undefined + 10; // NaN(undefined → NaN)
null + " text"; // "null text"
非严格相等
核心转换规则(优先级从高到低)
-
类型相同:直接比较值(行为与
===
相同)5 == 5 // true "a" == "a" // true
-
字符串 vs 数字:将字符串转为数字
"5" == 5 // true (Number("5") → 5) "" == 0 // true (Number("") → 0)
-
布尔值 vs 其他:将布尔值转为数字
true == 1 // true (Number(true) → 1) false == 0 // true (Number(false) → 0) true == "1" // true (true→1, "1"→1)
-
对象 vs 原始值:调用对象的
valueOf()
或toString()
转为原始值[1] == 1 // true ([1].toString() → "1" → 1) [1] == "1" // true [] == 0 // true ([]→""→0)
-
其他组合:尝试转为数字比较
true == [] // false (true→1, []→0 → 1 != 0)
特殊转换场景
-
null
和undefined
:互相宽松相等,和其他任何相比都不相等null == undefined // true undefined == null // true
-
NaN
和NaN
:不相等,和其他任何相比也都不相等
总结表
比较场景 | 转换规则 | 示例 | 结果 |
---|---|---|---|
null vs undefined | 直接相等 | null == undefined | true |
字符串 vs 数字 | 字符串 → 数字 | '5' == 5 | true |
布尔值 vs 任意 | 布尔值 → 数字 | true == 1 | true |
对象 vs 非对象 | 对象 → 原始值 → 数字 | [1] == 1 | true |
null /undefined vs 其他 | 不转换 | null == 0 | false |
数字 vs 非布尔原始值 | 尝试转为数字 | true == '1' | true |
附加知识
SameValue
SameValue 和 SameValueZero 是 JavaScript 中的两种比较算法
SameValue:
Object.is()
使用此算法,此算法和 ===
基本一致,但有两点不同
Object.is(NaN, NaN) // true
Object.is(0, -0) // false
SameValueZero:
Array.includes()
、Set.has()
使用此算法,此算法和 SameValue 的区别在于 +0 和 -0 是相等的
const s = new Set()
s.add(0)
s.add(NaN)
s.has(-0) // true
s.has(NaN) // true