JavaScript 条件判断和三元表达式
简介
在 JavaScript 中,条件判断用于控制程序的执行流程。常用的条件判断方式包括:if...else 语句、switch...case 语句、三元表达式(条件运算符),以及利用逻辑运算符的短路求值。
if…else 语句
基本语法
if (condition) {
// 条件为真时执行
} else {
// 条件为假时执行
}
示例
let age = 18;
if (age >= 18) {
console.log('你已成年');
} else {
console.log('你还未成年');
}
// 输出:你已成年
else if(多条件判断)
let score = 85;
if (score >= 90) {
console.log('优秀');
} else if (score >= 80) {
console.log('良好');
} else if (score >= 60) {
console.log('及格');
} else {
console.log('不及格');
}
// 输出:良好
嵌套 if…else
let age = 20;
let hasTicket = true;
if (age >= 18) {
if (hasTicket) {
console.log('可以进入');
} else {
console.log('需要购票');
}
} else {
console.log('年龄不足');
}
省略花括号(不推荐)
当代码块只有一条语句时,可以省略花括号,但不推荐,因为容易引发错误。
// 可以运行,但不推荐
if (true) console.log('Hello');
// 容易出错的情况
if (false)
console.log('这行不会执行');
console.log('这行无论条件如何都会执行!'); // 缩进有误导性
假值(falsy)在条件判断中
if 条件会自动将值转为布尔值,以下假值会被判定为假:
if (false) console.log('不会执行');
if (0) console.log('不会执行');
if ('') console.log('不会执行');
if (null) console.log('不会执行');
if (undefined) console.log('不会执行');
if (NaN) console.log('不会执行');
// 以下为真值
if ('0') console.log('会执行'); // 非空字符串为真
if ([]) console.log('会执行'); // 空数组为真
if ({}) console.log('会执行'); // 空对象为真
条件判断中的最佳实践
let value = null;
// 不推荐:与 true/false 直接比较
if (value == true) { ... }
if (value == false) { ... }
// 推荐:直接判断值本身
if (value) { ... } // 判断是否为真值
if (!value) { ... } // 判断是否为假值
// 判断是否为 null 或 undefined
if (value == null) { ... } // == 下 null 和 undefined 都匹配
if (value === null) { ... } // 只匹配 null
if (value === undefined) { ... } // 只匹配 undefined
switch…case 语句
基本语法
switch (expression) {
case value1:
// 当 expression === value1 时执行
break;
case value2:
// 当 expression === value2 时执行
break;
default:
// 以上都不匹配时执行
}
示例
let day = 3;
let dayName;
switch (day) {
case 1:
dayName = '星期一';
break;
case 2:
dayName = '星期二';
break;
case 3:
dayName = '星期三';
break;
case 4:
dayName = '星期四';
break;
case 5:
dayName = '星期五';
break;
default:
dayName = '周末';
}
console.log(dayName); // 星期三
break 的重要性
如果省略 break,会发生 fall-through(贯穿),即执行完匹配的 case 后继续执行后续 case。
let num = 1;
switch (num) {
case 1:
console.log('one');
// 没有 break!
case 2:
console.log('two');
// 没有 break!
case 3:
console.log('three');
break;
case 4:
console.log('four');
}
// 输出:
// one
// two
// three
利用 fall-through(有意为之)
有时 fall-through 是有用的,当多个 case 需要执行相同代码时:
let month = 2;
let days;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28;
break;
default:
days = -1; // 无效月份
}
console.log(days); // 28
switch 使用严格相等(===)
switch 中的比较使用的是严格相等 ===,不会进行类型转换。
let x = '10';
switch (x) {
case 10:
console.log('数字 10');
break;
case '10':
console.log('字符串 "10"');
break;
}
// 输出:字符串 "10"(不会匹配数字 10)
switch 的替代方案
当 case 较多时,使用对象映射可能更清晰:
// 使用 switch
function getDayNameSwitch(day) {
switch (day) {
case 1: return '星期一';
case 2: return '星期二';
case 3: return '星期三';
default: return '未知';
}
}
// 使用对象映射(更简洁)
function getDayNameMap(day) {
const days = {
1: '星期一',
2: '星期二',
3: '星期三'
};
return days[day] || '未知';
}
三元表达式(条件运算符)
语法
condition ? expr1 : expr2
- 如果
condition为真,返回expr1的值 - 如果
condition为假,返回expr2的值
基本示例
let age = 20;
let status = age >= 18 ? '成年' : '未成年';
console.log(status); // 成年
// 等价于:
let status2;
if (age >= 18) {
status2 = '成年';
} else {
status2 = '未成年';
}
与 if…else 的选择
适合使用三元表达式的场景:
// 简单的赋值
let isLoggedIn = user ? true : false;
// 设置默认值
let username = inputName || 'Guest';
// 或
let username = inputName !== undefined && inputName !== '' ? inputName : 'Guest';
// 函数返回
function getFee(isMember) {
return isMember ? '$2.00' : '$10.00';
}
不适合使用三元表达式的场景:
// 不推荐:复杂逻辑用三元表达式会降低可读性
let result = condition1 ? (condition2 ? (condition3 ? 'a' : 'b') : 'c') : 'd';
// 推荐:改用 if-else
let result;
if (condition1) {
if (condition2) {
result = condition3 ? 'a' : 'b';
} else {
result = 'c';
}
} else {
result = 'd';
}
嵌套三元表达式(谨慎使用)
let score = 85;
let grade = score >= 90 ? 'A' :
score >= 80 ? 'B' :
score >= 70 ? 'C' :
score >= 60 ? 'D' : 'F';
console.log(grade); // B
// 更清晰的写法:使用 if-else 或查找表
function getGrade(score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
}
短路求值作为条件判断
利用逻辑运算符 && 和 || 的短路特性,可以实现简洁的条件执行。
&& 实现条件执行
// 语法:condition && expression
// 当 condition 为真时,执行 expression;否则不执行
let isLoggedIn = true;
isLoggedIn && console.log('欢迎回来!'); // 会执行
isLoggedIn = false;
isLoggedIn && console.log('欢迎回来!'); // 不会执行
// 等价于:
if (isLoggedIn) {
console.log('欢迎回来!');
}
|| 设置默认值
// 语法:value || defaultValue
// 当 value 为假值时,使用 defaultValue
function greet(name) {
name = name || 'Guest';
console.log('Hello, ' + name);
}
greet(); // Hello, Guest
greet('Alice'); // Hello, Alice
// 注意:|| 会把 0、'' 等假值也替换掉
function multiply(a, b) {
a = a || 1; // 如果 a 是 0,会被替换为 1!
b = b || 1;
return a * b;
}
console.log(multiply(0, 5)); // 5(错了!应该是 0)
// 更好的方式:使用 ??(空值合并运算符,ES2020)
function multiply2(a, b) {
a = a ?? 1; // 只对 null 和 undefined 使用默认值
b = b ?? 1;
return a * b;
}
console.log(multiply2(0, 5)); // 0(正确)
?? 空值合并运算符(ES2020)
// ?? 只对 null 和 undefined 返回默认值,其他假值保持不变
console.log(null ?? 'default'); // "default"
console.log(undefined ?? 'default'); // "default"
console.log(0 ?? 'default'); // 0(保持 0)
console.log('' ?? 'default'); // ""(保持空字符串)
console.log(false ?? 'default'); // false(保持 false)
综合示例
示例 1:成绩等级判断
function getGradeInfo(score) {
if (score < 0 || score > 100) {
return { grade: '无效', comment: '分数必须在 0-100 之间' };
}
let grade = score >= 90 ? 'A' :
score >= 80 ? 'B' :
score >= 70 ? 'C' :
score >= 60 ? 'D' : 'F';
let comment = score >= 60 ? '及格' : '不及格';
return { grade, comment };
}
console.log(getGradeInfo(85)); // { grade: 'B', comment: '及格' }
console.log(getGradeInfo(55)); // { grade: 'F', comment: '不及格' }
示例 2:用户权限判断
function canAccess(user, resource) {
// 未登录
if (!user) return false;
// 管理员有所有权限
if (user.role === 'admin') return true;
// 根据资源类型判断
switch (resource.type) {
case 'public':
return true;
case 'premium':
return user.isPremium === true;
case 'private':
return user.id === resource.ownerId;
default:
return false;
}
}
// 测试
let admin = { role: 'admin' };
let member = { role: 'user', isPremium: true };
let resource = { type: 'premium' };
console.log(canAccess(admin, resource)); // true
console.log(canAccess(member, resource)); // true
console.log(canAccess(null, resource)); // false
示例 3:表单验证
function validateForm(form) {
let errors = [];
// 用户名验证
if (!form.username) {
errors.push('用户名不能为空');
} else if (form.username.length < 3) {
errors.push('用户名至少 3 个字符');
}
// 邮箱验证(简单检查)
let email = form.email;
if (!email) {
errors.push('邮箱不能为空');
} else if (!email.includes('@')) {
errors.push('邮箱格式不正确');
}
// 年龄验证
let age = form.age;
if (age == null) { // 检查 null 和 undefined
errors.push('年龄不能为空');
} else if (age < 18) {
errors.push('必须年满 18 岁');
}
// 返回结果
return {
isValid: errors.length === 0,
errors: errors
};
}
// 测试
let form = { username: 'ab', email: 'test', age: 16 };
let result = validateForm(form);
console.log(result.isValid); // false
console.log(result.errors); // ["用户名至少 3 个字符", "邮箱格式不正确", "必须年满 18 岁"]
总结:如何选择
| 场景 | 推荐方式 |
|---|---|
| 简单的二选一赋值 | 三元表达式 ? : |
| 多个互斥条件 | if...else if...else 或 switch |
| 根据表达式值匹配 | switch...case |
| 简单的条件执行 | && 短路求值 |
| 设置默认值 | ??(ES2020)或 || |
| 复杂的条件逻辑 | if...else(可读性更好) |
| 多个 case 执行相同逻辑 | switch 的 fall-through 或对象映射 |