减法(-)和乘法(*)运算符强制转为数字,不拼接字符串;5-"3"得2,"10"-"abc"得NaN,true-false得1,{}-[]得NaN;加法则优先字符串拼接。

JavaScript中减法(-)和乘法(*)运算符本身不直接进行字符串拼接,因此它们比加法更“倾向”数值计算,但依然会触发隐式类型转换——只是规则更聚焦于转为数字(Number),而非字符串。
减法运算(-)的类型转换逻辑
减法要求两个操作数都尽可能转为数字。它会依次尝试:
– 调用操作数的 valueOf(),若返回原始值则使用;
– 否则调用 toString(),再用 Number() 转换结果。
最终只要有一个无法转为有效数字,结果就是 NaN。
-
5 - "3"→5 - 3→2(字符串"3"被转为数字3) -
"10" - "abc"→10 - NaN→NaN("abc"转数字失败) -
true - false→1 - 0→1(布尔值转数字:true→1,false→0) -
{} - []→NaN - 0→NaN(空对象{}转字符串为"[object Object]",再转数字为NaN;空数组[]转数字为0)
乘法运算(*)的类型转换逻辑
乘法同样强制将操作数转为数字,转换步骤与减法一致,且对null、undefined、布尔值等有明确映射:
-
"6" * "7"→6 * 7→42 -
null * 8→0 * 8→0(null转数字为0) -
undefined * 2→NaN * 2→NaN(undefined转数字为NaN) -
["2"] * ["3"]→2 * 3→6(数组先toString()得字符串,再转数字)
与加法的关键区别
加法(+)遇到字符串会优先做拼接;而减法和乘法没有字符串连接语义,所以一见到非数字类型,就立刻走ToNumber抽象操作,不会退回到字符串处理。
-
"2" + "3"→"23"(字符串拼接) -
"2" - "3"→-1(强制数值计算) -
"2" * "3"→6(同上)
实际建议:避免依赖隐式转换
虽然减法和乘法的转换行为比加法更可预测,但仍可能引发意外NaN,尤其在处理用户输入、API返回值或DOM属性时。
立即学习“Java免费学习笔记(深入)”;
- 显式用
Number(x)、parseInt(x, 10)或parseFloat(x)转换,语义清晰且可控 - 对可能为
null/undefined的值,先做存在性判断或提供默认值:const val = x ?? 0; - 启用 ESLint 规则如
no-implicit-coercion,提醒避免-或*用于非数字意图的场景










