告别复杂if else!JavaScript条件判断的5个实用技巧
写代码时,我们经常要处理各种条件判断。简单的if else语句用起来很方便,但当逻辑变复杂时,代码就会变得又长又难懂。
今天分享几个让条件判断更简洁的方法,帮你写出更好的JavaScript代码。
传统的if else有什么问题?
先看一个常见的例子:
if (user.type === 'vip') {
// 处理VIP用户
} else if (user.type === 'member') {
// 处理会员用户
} else if (user.type === 'guest') {
// 处理游客
} else {
// 默认处理
}这还只是判断用户类型,如果业务逻辑更复杂,代码会变得很难维护。
技巧1:用对象映射代替条件判断
第一个方法很实用:把条件判断变成"查字典"。比如处理不同用户的折扣:
// 把条件和结果做成映射表
const discountMap = {
vip: 0.7, // VIP 7折
member: 0.9, // 会员9折
guest: 1 // 游客原价
};
function getDiscount(userType) {
return discountMap[userType] || 1; // 找不到就用默认值
}
// 使用起来很简单
const discount = getDiscount('vip'); // 返回0.7这种写法适合"一个条件对应一个结果"的场景,比如状态码处理:
const statusMessages = {
200: '请求成功',
404: '页面不存在',
500: '服务器错误'
};
function getStatusMessage(code) {
return statusMessages[code] || '未知状态';
}技巧2:用数组的includes方法
第二个技巧适合检查一个值是否在多个可能值中。比如错误状态判断:
// 以前的写法
if (status === 'failed' || status === 'error' || status === 'rejected') {
handleError();
}
// 现在的写法
const errorStatus = ['failed', 'error', 'rejected'];
if (errorStatus.includes(status)) {
handleError();
}在表单验证中特别有用:
// 定义有效的用户类型
const validUserTypes = ['admin', 'vip', 'member', 'guest'];
function validateUser(user) {
if (!validUserTypes.includes(user.type)) {
throw new Error('用户类型无效');
}
}
// 或者更简洁的写法
const isValidUser = validUserTypes.includes(user.type);技巧3:三元运算符简化赋值
第三个技巧适合简单的条件赋值。比如根据加载状态显示不同文字:
// 以前的写法
let statusText;
if (isLoading) {
statusText = '加载中...';
} else {
statusText = '加载完成';
}
// 现在的写法
const statusText = isLoading ? '加载中...' : '加载完成';多层条件也可以写得清晰:
const message = isSuccess
? '操作成功'
: hasError
? '操作失败'
: '处理中';但要注意,嵌套最好不要超过两层,否则会影响可读性。
技巧4:利用逻辑运算符的短路特性
第四个技巧使用&&和||的短路特性。比如权限检查:
// 以前的写法
if (user && user.hasPermission) {
executeOperation();
}
// 现在的写法
user?.hasPermission && executeOperation();设置函数参数默认值:
// 传统写法
function createUser(options) {
const config = options || {};
const name = config.name || '匿名用户';
const age = config.age || 18;
}
// 现代写法
function createUser(options = {}) {
const { name = '匿名用户', age = 18 } = options;
}实际应用例子:
// 组件渲染
function UserProfile({ user }) {
return (
<div>
{user?.avatar && <img src={user.avatar} />}
<h2>{user?.name || '匿名用户'}</h2>
</div>
);
}技巧5:使用Proxy代理处理复杂逻辑
第五个技巧比较高级,但很实用。vue3就用了Proxy。比如实现api的权限控制:
// 定义原始API方法
const api = {
deleteData: () => console.log('删除数据'),
updateData: () => console.log('更新数据'),
readData: () => console.log('读取数据')
};
// 权限检查函数
function checkPermission(methodName) {
const userPermissions = ['readData', 'updateData']; // 用户有的权限
return userPermissions.includes(methodName);
}
// 创建代理
const securedApi = new Proxy(api, {
get(target, methodName) {
const method = target[methodName];
// 如果不是函数或者是权限检查方法,直接返回
if (typeof method !== 'function') {
return method;
}
// 返回一个包装函数
return function(...args) {
if (!checkPermission(methodName)) {
console.log(`没有执行 ${methodName} 的权限`);
return null;
}
console.log(`执行: ${methodName}`);
return method.apply(target, args);
};
}
});
// 使用
securedApi.readData(); // 正常执行
securedApi.deleteData(); // 输出"没有执行 deleteData 的权限"另一个实际例子:数据验证代理
function createValidatedObject(obj, rules) {
return new Proxy(obj, {
set(target, property, value) {
// 检查是否有验证规则
if (rules[property] && !rules[property](value)) {
console.log(`属性 ${property} 的值 ${value} 无效`);
return false; // 阻止赋值
}
target[property] = value;
return true;
}
});
}
// 定义验证规则
const validationRules = {
age: (value) => value >= 0 && value <= 150,
email: (value) => value.includes('@')
};
const user = createValidatedObject({}, validationRules);
user.age = 25; // 成功
user.age = -5; // 失败,输出错误信息什么时候还是该用if else?
虽然上面这些技巧很好用,但if else在某些情况下仍然是更好的选择:
1. 范围判断
// if else更合适
if (score >= 90 && score <= 100) {
grade = 'A';
} else if (score >= 80 && score < 90) {
grade = 'B';
}2. 复杂条件组合
// 多个条件的复杂逻辑
if ((user.isAdmin || user.isModerator) &&
post.isPublished &&
!post.isDeleted) {
showEditButton();
}3. 需要清晰代码流程时
// 步骤清晰的业务逻辑
if (userNotExist) {
createNewUser();
} else if (userIsInactive) {
reactivateUser();
} else {
updateUserInfo();
}实际项目中的综合应用
看看在实际项目中怎么组合使用这些技巧:
class UserService {
constructor() {
this.rolePermissions = {
admin: ['read', 'write', 'delete', 'manage'],
editor: ['read', 'write'],
viewer: ['read']
};
this.statusMessages = {
active: '用户活跃',
inactive: '用户未激活',
suspended: '用户已停用'
};
}
// 使用对象映射
canUserPerformAction(user, action) {
const permissions = this.rolePermissions[user.role] || [];
return permissions.includes(action);
}
// 使用三元运算符和逻辑运算符
getUserDisplayInfo(user) {
const status = this.statusMessages[user.status] || '状态未知';
const canEdit = this.canUserPerformAction(user, 'write');
return {
name: user.name || '匿名用户',
status: status,
showEditButton: canEdit && user.isActive,
// 多层三元运算
badgeColor: user.role === 'admin' ? 'red' :
user.role === 'editor' ? 'blue' : 'gray'
};
}
// 使用数组includes
isValidUserRole(role) {
const validRoles = Object.keys(this.rolePermissions);
return validRoles.includes(role);
}
}总结
记住这几个技巧:
对象映射 - 适合"键值对"式的条件判断
数组includes - 适合检查值是否在某个集合中
三元运算符 - 适合简单的条件赋值
逻辑运算符 - 适合短路求值和默认值设置
Proxy代理 - 适合复杂的拦截和验证逻辑
选择哪种方法要看具体场景。目标是让代码更易读、易维护,而不是盲目追求"高级"写法。好的代码应该像说话一样自然,让别人一看就懂。希望这些技巧能帮你写出更简洁的JavaScript代码!
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!