- 文档
- 教程
- 前端
【免费下载链接】zh.javascript.info
现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。
JavaScript 的运算符在求值时并非"所见即所得":二元+会优先拼接字符串,而-、*、/等算术运算符则会把运算元强制转换为数字。本文以现代 JavaScript 教程(zh.javascript.info)中"基础运算符"章节的经典练习题3-primitive-conversions-questions/task.md为骨架,逐题推演 14 个表达式的结果,并对照官方答案解析与类型转换章节中的转换规则表,帮你彻底掌握字符串转换、数字转换、null/undefined特例以及运算符优先级这四组核心知识点。读完本文,你能准确口算出任意混合了字符串与数字的表达式结果,并能在实战中避开prompt取数相加这类典型陷阱。
题目背景与知识前提
该练习题位于 1-js/02-first-steps/08-operators/ 目录下,是"基础运算符,数学运算"一章的配套任务(importance: 5,即难度与重要性均为最高档)。它要求读者在不运行代码的情况下,先手写 14 个表达式的结果,再与官方答案比对。
要独立完成这道题,需要先掌握两章前置知识:
- 原始类型的转换规则:
07-type-conversions/article.md中的数字型转换规则表; - 运算符的求值行为:
08-operators/article.md中二元+的字符串连接特性、一元+的数字转换,以及运算符优先级表。
下面先速览规则,再逐题推演。
三大原始类型转换规则速览
在进行算术运算时,JavaScript 会自动把运算元转换为数字。根据类型转换章节中的规则表,数字型转换遵循:
| 值 | 转换为数字的结果 |
|---|---|
undefined | NaN |
null | 0 |
true/false | 1/0 |
string | 去掉首尾空白(空格、\n、\t等)后"读取"其中的数字;剩余为空则得0,读取出错则得NaN |
两个最容易被记错的特例是:
undefined转数字是NaN,而不是0(null才是0);- 字符串转数字时,首尾空白会被忽略,因此
" -9 "可以转为-9,而只有空白字符的" \t \n"等价于空字符串,转为0。
同时要区分两种运算符行为(详见运算符章节):
- 二元加号
+是唯一支持字符串连接的算术运算符:只要有一个运算元是字符串,另一个也会被转为字符串,然后拼接; - 其余算术运算符(
-、*、/等)只对数字起作用,总是把运算元转换为数字后再计算; - 一元加号
+等价于Number(...),优先级(15)高于二元加号(12),所以+a + +b中先各自转数字、再求和。
14 道表达式逐题推演
原始题目与答案代码如下(no-beautify表示刻意保留紧凑格式以便对比):
"" + 1 + 0 // "10" "" - 1 + 0 // -1 true + false // 1 6 / "3" // 2 "2" * "3" // 6 4 + 5 + "px" // "9px" "$" + 4 + 5 // "$45" "4" - 2 // 2 "4px" - 2 // NaN " -9 " + 5 // " -9 5" " -9 " - 5 // -14 null + 1 // 1 undefined + 1 // NaN " \t \n" - 2 // -2下面按规则分组,逐条拆解。
第一组:二元+的"字符串优先"规则
"" + 1 + 0→"10":有字符串参与的加法会先做字符串转换。第一步"" + 1把数字1转为字符串得到"1";第二步"1" + 0再次应用同一规则,得到"10"。官方答案的注释 (1) 指出:只要任一运算元是字符串,另一个也会被转换。
4 + 5 + "px"→"9px":运算符按从左到右的顺序工作(同级优先级下),所以先计算4 + 5 = 9,此时仍是纯数字加法;随后9 + "px"遇到字符串,把9转为"9"拼接,得到"9px"。这正是运算符章节中2 + 2 + '1' = "41"例子的翻版——结果的类型取决于运算顺序。
"$" + 4 + 5→"$45":第一个运算元就是字符串,因此后续的4和5都被视为字符串参与拼接,最终得到"$45",而不是"$" + 9。对照运算符章节的'1' + 2 + 2 = "122"即可理解:一旦进入"字符串模式",整条链都会拼接。
" -9 " + 5→" -9 5":这同样属于字符串拼接(官方注释 (3) 说明"带字符串的加法会将数字5加到字符串之后")。注意字符串内容原样保留,包括首尾空格,所以结果是带空格的" -9 5",绝不会变成-4。
第二组:减乘除触发的数字转换
"" - 1 + 0→-1:减法-与加法不同,它只接受数字。空字符串""按数字转换规则变成0,于是表达式等价于0 - 1 + 0 = -1。官方注释 (2) 特意强调:"减法(像大多数数学运算一样)只能用于数字"。
true + false→1:这里没有字符串,二元+退化为普通加法;布尔值按规则转为数字true → 1、false → 0,因此1 + 0 = 1。
6 / "3"→2:除法要求数字运算元,"3"被转为3,得到2。运算符章节中'6' / '2'的例子与此同理。
"2" * "3"→6:乘法同样把两个字符串都转为数字,2 * 3 = 6。这是"其他算术运算符总是转换运算元"的最直观证据。
"4" - 2→2:"4"转为数字4,4 - 2 = 2。减法没有字符串拼接行为,只做数字运算。
"4px" - 2→NaN:这是最容易踩坑的一题。字符串"4px"不是"纯数字字符串":数字转换会从"4px"中读取数字,读到p时解析失败,整体结果为NaN。官方注释 (6) 的姊妹例在类型转换章节中也有对应说明——Number("123z")同样得到NaN(读到z时出错)。一旦出现NaN,后续算术结果永远保持NaN。
" -9 " - 5→-14:与上一题形成鲜明对比。" -9 "去掉首尾空格后是-9,是合法的数字字符串,转为-9后计算-9 - 5 = -14。官方注释 (4) 强调:"减法始终将字符串转换为数字,因此它会使" -9 "转换为数字-9(忽略了字符串首尾的空格)。"
第三组:null、undefined与空白字符串特例
null + 1→1:null按数字转换规则变为0(官方注释 (5)),所以0 + 1 = 1。这是null与undefined在转换上最关键的差异点。
undefined + 1→NaN:undefined转为数字是NaN(官方注释 (6)),NaN + 1仍是NaN。官方答案与类型转换章节的规则表都对此做了双重强调,因为初学者常误以为它和null一样是0。
" \t \n" - 2→-2:整个字符串只包含空白字符(空格、制表符\t、换行符\n)。字符串转数字时会先去掉首尾空白,剩余为空字符串,按规则转为0,所以0 - 2 = -2。官方注释 (7) 的表述是:"字符串转换为数字时,会忽略字符串的首尾处的空格字符……整个字符串由空格字符组成……类似于空字符串,所以会变为0。"
从解析中提炼的四个记忆要点
- 先看有没有字符串,再看运算符:只要二元
+的任一运算元是字符串,结果一定是字符串拼接;而-、*、/出现时,永远走数字转换路线。 +是"双面派":一元+做数字转换(等价Number(...)),优先级高于二元+,这是+a + +b能正确求和的原因。null与undefined在数字转换中天差地别:null → 0,undefined → NaN。- 空白与非法字符:字符串转数字会忽略首尾空白,纯空白字符串视为
0;但只要混入非数字字符(如"4px"),结果就是NaN。
实战延伸:prompt输入相加的陷阱
这 14 道题并非纸上谈兵,同样的坑在真实代码中随时会出现。本目录配套的练习题4-fix-prompt/task.md就展示了一个经典 bug:
let a = prompt("First number?", 1); let b = prompt("Second number?", 2); alert(a + b); // 12prompt总是以字符串形式返回用户输入,所以这里实际执行的是"1" + "2",二元+走了字符串拼接路线,输出12而非3。官方解答给出了两种修正方式:
// 方式一:在 prompt 前用一元 + 立即转数字 let a = +prompt("First number?", 1); let b = +prompt("Second number?", 2); alert(a + b); // 3// 方式二:在 alert 中同时使用一元与二元 + let a = prompt("First number?", 1); let b = prompt("Second number?", 2); alert(+a + +b); // 3方式二正是本题目核心规则的实战应用:两个一元+的优先级(15)都高于中间的二元+(12),因此先完成"1" → 1、"2" → 2的数字转换,二元+再对两个数字求和。理解这 14 道表达式,就能一眼看出这类 bug 的成因,并熟练运用一元+或Number(...)修复。
自测与延伸阅读
建议按照原题要求先遮住答案,在白纸上写出全部 14 个表达式的结果,再对照官方答案逐条核对;凡是写错的题目,回到类型转换章节的规则表和运算符章节的优先级表重新确认对应规则。
若想进一步巩固运算符求值直觉,本目录还提供配套练习:1-increment-order(自增/自减的前置与后置返回值)与2-assignment-result(赋值表达式也返回值)。这三道题共同覆盖了"运算符返回值 + 类型转换 + 优先级"三大求值要素,吃透后即可流畅阅读任何混合表达式代码。
- 文档
- 教程
- 前端
【免费下载链接】zh.javascript.info
现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。
相关推荐
JavaScript 基础类型转换表达式逐题解析——JavaScript.info 运算符章节经典练习
JavaScript 基础类型转换表达式逐题解析——JavaScript.info 运算符章节经典练习 本文围绕 JavaScript.info(Modern
文档/教程前端原始值类型转换实战:Modern JavaScript Tutorial 运算符类型转换练习题全解析
原始值类型转换实战:Modern JavaScript Tutorial 运算符类型转换练习题全解析 本篇指南围绕 Modern JavaScript Tuto
文档/教程前端JavaScript 比较运算符专项练习:7 道经典表达式逐题解析(Modern JavaScript Tutorial 实战)
JavaScript 比较运算符专项练习:7 道经典表达式逐题解析(Modern JavaScript Tutorial 实战) 导读 本篇技术指南围绕 Mod
文档/教程前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考