Skip to content

10|JavaScript 条件判断

程序需要根据数据状态执行不同的逻辑:如果磁盘使用率超过 90%,发送告警;如果用户是管理员,显示管理菜单。条件判断让代码具备分支能力。JavaScript 的条件语法和大多数编程语言类似,但真值判断规则有自己的特点。

一、if / else

js
const usage = 92;

if (usage >= 90) {
  console.log("严重:磁盘使用率超过 90%");
} else if (usage >= 80) {
  console.log("警告:磁盘使用率超过 80%");
} else {
  console.log("磁盘使用率正常");
}

条件表达式放在括号中,代码块用大括号包裹。即使代码块只有一行,也建议保留大括号——省略大括号后,后续增删代码容易引入 bug:

js
// 危险:缩进具有误导性
if (isAdmin)
  console.log("管理员");
  deleteUser();   // 这行不受 if 控制,总是执行

// 正确:始终使用大括号
if (isAdmin) {
  console.log("管理员");
  deleteUser();
}

二、三元表达式

简单的 if/else 可以用三元运算符简写:

js
const status = isRunning ? "运行中" : "已停止";

// 等价于
let status;
if (isRunning) {
  status = "运行中";
} else {
  status = "已停止";
}

三元表达式适合赋值场景。嵌套过深时会降低可读性:

js
// 不建议:嵌套三元难以阅读
const label = count === 0 ? "无" : count < 10 ? "少量" : "大量";

// 建议:用 if/else 或查表
let label;
if (count === 0) {
  label = "无";
} else if (count < 10) {
  label = "少量";
} else {
  label = "大量";
}

三、switch

多个等值判断时,switch 比连续的 if/else 更清晰:

js
const level = "critical";

switch (level) {
  case "info":
    console.log("信息级别");
    break;
  case "warning":
    console.log("警告级别");
    break;
  case "critical":
    console.log("严重级别");
    break;
  default:
    console.log("未知级别");
}

每个 case 结束时要写 break。如果省略 break,程序会继续执行下一个 case(称为"穿透"):

js
// 利用穿透:多个 case 共享同一段逻辑
switch (level) {
  case "warning":
  case "critical":
    console.log("需要处理");   // warning 和 critical 都会执行这里
    break;
  case "info":
    console.log("仅记录");
    break;
}

switch 使用 === 做比较,类型不匹配不会命中:

js
const code = "404";

switch (code) {
  case 404:           // 不会命中,因为 "404" !== 404
    console.log("数字 404");
    break;
  case "404":         // 命中
    console.log("字符串 404");
    break;
}

四、真值与假值

条件判断中,不是所有值都按 true/false 处理。以下值在条件中会被当作 false

假值(falsy)
false
0
""(空字符串)
null
undefined
NaN

其余所有值都是真值(truthy),包括:

js
if ("0") { }       // 真值(非空字符串)
if ("false") { }   // 真值(非空字符串)
if ([]){ }         // 真值(空数组是对象)
if ({}) { }        // 真值(空对象)

空值合并运算符

js
const port = config.port ?? 8080;

?? 只在左边为 nullundefined 时返回右边。和 || 的区别:

js
const a = 0 || 8080;        // 8080(0 是 falsy)
const b = 0 ?? 8080;        // 0(0 不是 null/undefined)

const c = "" || "default";  // "default"(空字符串是 falsy)
const d = "" ?? "default";  // ""(空字符串不是 null/undefined)

配置项可能为 0"" 时,用 ?? 更合适。

五、可选链操作符

访问深层嵌套对象属性时,如果中间某层为 nullundefined,直接访问会报错:

js
const data = { user: null };
console.log(data.user.name);   // TypeError: Cannot read property 'name' of null

可选链 ?. 在遇到 nullundefined 时安全返回 undefined

js
console.log(data.user?.name);           // undefined,不报错
console.log(data.user?.address?.city);  // undefined

配合 ?? 设置默认值:

js
const city = data.user?.address?.city ?? "未知";

六、常见错误

用 == 做条件判断

js
// 错误
if (count == "5") {
  // count 为 5 时也会命中
}

// 正确
if (count === 5) {

忘记 break 导致穿透

js
switch (level) {
  case "warning":
    console.log("警告");
    // 忘记 break,会继续执行 critical 的逻辑
  case "critical":
    console.log("严重");
    break;
}

用 if 判断空数组

js
const arr = [];

// 错误:空数组是真值
if (arr) {
  console.log("数组有元素");   // 会执行,但数组为空
}

// 正确:判断长度
if (arr.length > 0) {
  console.log("数组有元素");
}

条件判断中隐式转换的陷阱

js
// 意图:如果没有设置名称,用默认值
const name = inputName || "未命名";

// 问题:输入 "0" 时会被当作 falsy,fallback 到 "未命名"
// 解决:如果 "0" 是合法值,用 ??
const name = inputName ?? "未命名";