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;
}

下一篇:循环语句