Menu

JavaScript if/else 语句:条件判断、else if 与三元运算符

JavaScript 中 if/else 的工作方式:条件、else if 链、真值判断的坑,以及何时改用三元运算符。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

if 语句的结构

if 语句只在条件为真时才执行一段代码。它的结构是:一个关键字、括号里的条件,以及花括号里的代码块:

条件 age >= 18 的结果是 true,所以代码块会执行。如果 age 是 16,条件就会是 false,JavaScript 会完全跳过这个代码块。

当代码块只有一条语句时,花括号在技术上是可选的,但请始终写上。不带花括号的 if 语句是一个经典的 bug 来源:以后有人加了第二行,却忘了这一行其实并不在代码块里。

else:兜底分支

把 if 和 else 搭配起来,就能在条件为假时执行另一段代码:

两个分支中恰好只有一个会执行。不会两个都执行,也不会一个都不执行。else 没有自己的条件,它负责兜住“if 为假”的所有情况。

else if:从多个选项中选一个

当情况多于两种时,用 else if 把它们串起来。JavaScript 按顺序检查每个条件,遇到第一个为真的就停止:

只有一个分支会执行。一旦某个条件匹配,其余的都会被跳过,即使它们也为真。这就是顺序很重要的原因:如果你把链条反过来,先检查 score >= 60,那么所有 60 分以上的人都会得到 D。

最后的 else 是可选的,但写上它能让你的意图更清楚:“如果其他条件都不匹配,就执行这里。”

条件可以是任何表达式

括号里的内容不一定是比较运算。它可以是任何表达式,JavaScript 会把结果转换成布尔值:

非空字符串是真值。0 和空字符串是假值,所以当 items.length 为 0 时会走 else 分支。这是 JavaScript 中“检查是否有内容”的标准写法。

假值的完整列表很短,值得记住:false、0、-0、0n、""、null、undefined 和 NaN。其他所有值都是真值,包括 "0"、"false"、[] 和 {}。最后两个常常让人上当。

组合条件:&& 和 ||

用 &&(与)和 ||(或)来组合条件:

&& 要求两边都是真值,|| 要求至少一边是真值。两者都会短路:&& 遇到第一个假值就停止,|| 遇到第一个真值就停止。当第二个条件有副作用或者可能抛出异常时,这一点就很重要:如果 user 是 null,user && user.name 会安全地返回 undefined,而不会报错。

混合使用时,用括号把逻辑包起来,让优先级一目了然:

不加括号的话,&& 的优先级比 || 高,而这通常和自然的阅读习惯相反。

== 与 ===(请用 ===)

在 if 中判断相等时,用 === 和 !==,而不是 == 和 !=:

== 在比较之前会转换类型,从而导致一些意外,比如 "" == 0 为 true,null == undefined 也为 true。=== 比较时不做类型转换:类型相同且值相同才相等。默认使用 ===。唯一常见的例外是 x == null,它可以一次性检查 null 和 undefined。

三元运算符

在两个值之间做选择时,三元运算符 condition ? a : b 通常比完整的 if/else 更简洁:

三元运算符是一个表达式,它会产生一个值。这是它和 if/else(一条语句)的关键区别。需要结果时(给变量赋值、返回值、拼接字符串)用三元运算符;执行有副作用的操作时用 if/else。

三元运算符可以链式嵌套,但可读性会断崖式下降:

// Don't do this:
const grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F";

如果要链式嵌套,就回到 else if。

嵌套 if 与扁平的 else if

有时一个条件只有在另一个条件成立时才有意义。这种情况下嵌套没问题:

但嵌套三四层就是一种代码坏味道了。用提前返回或者合并条件把它展平:

提前返回让每个分支都很短,而且处在同一缩进层级。这比层层嵌套的 if 金字塔好读得多。

常见陷阱:在 if 中赋值

= 是赋值,=== 是比较。在条件中把两者搞混是一个经典 bug:

status = "done" 会把 "done" 赋给 status,并且表达式的值就是 "done",这是真值,所以代码块总会执行,而你已经在不知不觉中覆盖了这个变量。代码检查工具(linter)能发现这个问题,严格模式则不能。多加小心,想比较时就用 ===。

下一步:switch

当你要把一个值和许多可能的匹配项进行比较时,长长的 else if 链就开始显得重复。JavaScript 的 switch 语句正是为这种情况设计的,它在 break 和贯穿(fall-through)方面也有自己的特点,这就是下一页的内容。

常见问题

JavaScript 中如何写 if/else 语句?

在 if 后面的括号里写条件,然后是花括号包起来的代码块。接着写 else 和另一个代码块作为兜底分支。例如:if (age >= 18) { console.log('adult'); } else { console.log('minor'); }。条件可以是任何表达式,JavaScript 会把它转换成布尔值。

JavaScript 中 else if 和嵌套 if 有什么区别?

else if 把多个条件串联起来,只有一个分支会执行:JavaScript 按顺序检查每个条件,遇到第一个匹配的就停止。嵌套 if 则是把一个 if 放进另一个里,通常用于只在第一个条件为真时才检查第二个条件。扁平的 else if 链几乎总是比层层嵌套的 if 更容易阅读。

什么时候应该用三元运算符代替 if/else?

当你在表达式中从两个值里选一个时,用三元运算符 condition ? a : b:给变量赋值、从函数返回、拼接字符串。当分支执行的是有副作用的语句,或者任何一边不止是一个简短的表达式时,坚持用 if/else。三元运算符一旦链式嵌套,很快就变得难以阅读。

为什么 JavaScript 中 if (0) 的表现和 if (false) 不一样?

其实没有不一样,两者都会跳过代码块。JavaScript 会把条件转换成布尔值,而 0、''、null、undefined、NaN 和 false 都是假值。真正的坑在于,'0'(非空字符串)和 [](空数组)这类值是真值,这会让从其他语言过来的人感到意外。

Coddy 编程语言插图

和 Coddy 一起学编程

开始