JavaScript 条件语句
概述
条件语句用于根据不同条件执行不同的代码块,是程序控制流程的基础。
if 语句
基本语法
// 单一条件
if (condition) {
// 条件为true时执行
}
// if-else
if (condition) {
// 条件为true时执行
} else {
// 条件为false时执行
}
// 多重条件
if (condition1) {
// condition1为true时执行
} else if (condition2) {
// condition2为true时执行
} else {
// 所有条件都为false时执行
}
实际应用
// 成绩评级系统
function getGrade(score) {
if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else if (score >= 70) {
return "C";
} else if (score >= 60) {
return "D";
} else {
return "F";
}
}
// 权限检查
function checkAccess(user) {
if (!user) {
throw new Error("用户未登录");
} else if (!user.active) {
throw new Error("用户账户已禁用");
} else if (!user.permissions.read) {
throw new Error("权限不足");
} else {
return true;
}
}
条件表达式的类型转换
// 假值(falsy values)
if (false) { /* 不执行 */ }
if (0) { /* 不执行 */ }
if ("") { /* 不执行 */ }
if (null) { /* 不执行 */ }
if (undefined) { /* 不执行 */ }
if (NaN) { /* 不执行 */ }
// 真值(truthy values)
if (true) { /* 执行 */ }
if (1) { /* 执行 */ }
if("hello") { /* 执行 */ }
if([]) { /* 执行 - 空数组是真值! */ }
if({}) { /* 执行 - 空对象是真值! */ }
三元运算符
基本语法
condition ? valueIfTrue : valueIfFalse
使用示例
// 简单条件赋值
const status = age >= 18 ? "成人" : "未成年";
// 函数参数默认值(ES6之前的方法)
function greet(name) {
name = name ? name : "游客";
return `你好,${name}!`;
}
// 嵌套三元运算符(不推荐)
const level = score >= 90 ? "优秀" :
score >= 75 ? "良好" :
score >= 60 ? "及格" : "不及格";
// 推荐用if-else代替复杂的嵌套三元运算符
function getLevel(score) {
if (score >= 90) return "优秀";
if (score >= 75) return "良好";
if (score >= 60) return "及格";
return "不及格";
}
switch 语句
基本语法
switch (expression) {
case value1:
// expression === value1时执行
break;
case value2:
// expression === value2时执行
break;
default:
// 没有匹配的case时执行
break;
}
实际应用
// 星期判断
function getDayType(day) {
switch (day) {
case 0:
case 6:
return "周末";
case 1:
case 2:
case 3:
case 4:
case 5:
return "工作日";
default:
return "无效日期";
}
}
// HTTP状态码处理
function handleResponse(statusCode) {
switch (statusCode) {
case 200:
console.log("请求成功");
break;
case 404:
console.log("资源未找到");
break;
case 500:
console.log("服务器错误");
break;
default:
console.log(`未知状态码: ${statusCode}`);
}
}
// 使用对象替代switch(现代方法)
const statusMessages = {
200: "请求成功",
404: "资源未找到",
500: "服务器错误"
};
function handleResponseModern(statusCode) {
const message = statusMessages[statusCode] || `未知状态码: ${statusCode}`;
console.log(message);
}
switch的特殊情况
穿透行为(Fall-through)
// 有意的穿透
function getSeasonFromMonth(month) {
let season;
switch (month) {
case 12:
case 1:
case 2:
season = "冬季";
break;
case 3:
case 4:
case 5:
season = "春季";
break;
case 6:
case 7:
case 8:
season = "夏季";
break;
case 9:
case 10:
case 11:
season = "秋季";
break;
default:
season = "无效月份";
}
return season;
}
// 意外的穿透(bug)
function buggyFunction(value) {
switch (value) {
case 1:
console.log("一");
// 忘记break,会继续执行下一个case
case 2:
console.log("二");
break;
default:
console.log("其他");
}
}
buggyFunction(1); // 输出: "一" 和 "二"
最佳实践
1. 条件表达式的优化
// 避免复杂的条件表达式
// 不好
if (user && user.profile && user.profile.settings && user.profile.settings.theme === 'dark') {
// 处理暗黑主题
}
// 更好:使用可选链(ES2020)
if (user?.profile?.settings?.theme === 'dark') {
// 处理暗黑主题
}
// 或提取为变量
const isDarkTheme = user?.profile?.settings?.theme === 'dark';
if (isDarkTheme) {
// 处理暗黑主题
}
2. 早期返回模式
// 不好:多层嵌套
function processUser(user) {
if (user) {
if (user.active) {
if (user.permissions) {
// 处理用户
return processActiveUser(user);
}
}
}
return null;
}
// 好:早期返回
function processUser(user) {
if (!user) return null;
if (!user.active) return null;
if (!user.permissions) return null;
return processActiveUser(user);
}
3. 使用Map替代大型switch
// 传统switch
function getAnimalSound(animal) {
switch (animal) {
case 'dog': return '汪汪';
case 'cat': return '喵喵';
case 'cow': return '哞哞';
case 'pig': return '哼哼';
// ... 更多动物
default: return '未知';
}
}
// 使用Map
const animalSounds = new Map([
['dog', '汪汪'],
['cat', '喵喵'],
['cow', '哞哞'],
['pig', '哼哼']
]);
function getAnimalSound(animal) {
return animalSounds.get(animal) || '未知';
}
4. 条件语句的性能考虑
// 将最常见的条件放在前面
function getResponseTime(statusCode) {
// 200是最常见的状态码,放在最前面
if (statusCode === 200) {
return 'fast';
} else if (statusCode === 404) {
return 'medium';
} else if (statusCode === 500) {
return 'slow';
} else {
return 'unknown';
}
}
// 对于大量条件,使用对象查找更高效
const responseTimeMap = {
200: 'fast',
404: 'medium',
500: 'slow'
};
function getResponseTimeFast(statusCode) {
return responseTimeMap[statusCode] || 'unknown';
}
常见陷阱
1. 赋值与比较混淆
// 错误:使用赋值而不是比较
if (x = 5) { // 应该是 x === 5
console.log("这总是会执行,除非x被赋值为假值");
}
// 正确
if (x === 5) {
console.log("x等于5时才执行");
}
2. 类型转换陷阱
// 意外的类型转换
console.log(0 == false); // true
console.log("" == false); // true
console.log([] == false); // true
console.log(null == undefined); // true
// 使用严格比较避免意外转换
console.log(0 === false); // false
console.log("" === false); // false
console.log([] === false); // false
console.log(null === undefined); // false
3. switch语句的严格比较
const value = "1";
switch (value) {
case 1: // 数字1,不会匹配字符串"1"
console.log("不会执行");
break;
case "1": // 字符串"1",会匹配
console.log("会执行");
break;
}