JavaScript 逻辑判断进阶:从 if-else 到 Map 的高级用法
本文深入探讨 JavaScript 中复杂逻辑判断的多种实现方式。从基础的 if-else 和 switch 语句出发,逐步演示如何利用对象属性映射和 Map 对象简化单一条件判断。针对多重条件场景,介绍了字符串拼接键、嵌套 Map 以及正则表达式匹配等高级技巧,旨在帮助开发者写出更简洁、易维护且高效的代码。
JavaScript 逻辑判断的演进
在 JavaScript 开发中,处理复杂的业务逻辑判断是常见需求。虽然 if-else 和 switch 语句能解决大部分问题,但随着条件分支的增加,代码往往会变得冗长且难以维护。为了提升代码的可读性和扩展性,我们需要探索更优雅的逻辑处理方案。
假设我们有一段处理按钮点击事件的代码,需要根据不同的活动状态执行日志记录和页面跳转操作。
const onButtonClick = (status) => {
if (status == 1) {
sendLog('processing')
jumpTo('IndexPage')
} else if (status == 2) {
sendLog('fail')
jumpTo('FailPage')
} else if (status == 3) {
sendLog('fail')
jumpTo('FailPage')
} else if (status == 4) {
sendLog('success')
jumpTo('SuccessPage')
} else if (status == 5) {
sendLog('cancel')
jumpTo('CancelPage')
} else {
sendLog('other')
jumpTo('Index')
}
}
观察上述按钮点击逻辑,它根据活动状态的不同,分别执行发送日志埋点和跳转至对应页面的操作。直观地看,这段代码可以通过 switch 语句进行重构。
使用 switch 优化条件分支
const onButtonClick = (status) => {
switch (status) {
case 1:
sendLog('processing')
jumpTo('IndexPage')
break
case 2:
case 3:
sendLog('fail')
jumpTo('FailPage')
break
case 4:
sendLog('success')
jumpTo('SuccessPage')
break
case 5:
sendLog('cancel')
jumpTo('CancelPage')
break
default:
sendLog('other')
jumpTo('Index')
break
}
}
重构后的 switch 结构确实比嵌套的 if-else 更加清晰。值得注意的是,当 case 2 和 case 3 执行相同的逻辑时,可以省略 case 2 中的处理代码,利用 case 穿透特性,使 case 2 直接执行 case 3 的逻辑。
然而,还有更简洁的实现方式:
利用对象映射简化单一判断
const actions = {
'1': ['processing', 'IndexPage'],
'2': ['fail', 'FailPage'],
'3': ['fail', 'FailPage'],
'4': ['success', 'SuccessPage'],
'5': ['cancel', 'CancelPage'],
default: ['other', 'Index'],
}
const onButtonClick = (status) => {
let action = actions[status] || actions['default'],
logName = action[0],
pageName = action[1]
sendLog(logName)
jumpTo(pageName)
}
这种写法显著提升了代码的整洁度。其核心思想是将判断条件作为对象的键,将处理逻辑作为对应的值。在按钮点击时,通过对象属性查找的方式直接获取并执行逻辑,这种方法特别适用于单一条件的判断场景。
既然对象映射有效,是否还有其他编码方式?答案是肯定的。
Map 对象在单一判断中的应用
const actions = new Map([
[1, ['processing', 'IndexPage']],
[2, ['fail', 'FailPage']],
[3, ['fail', 'FailPage']],
[4, ['success', 'SuccessPage']],
[5, ['cancel', 'CancelPage']],
['default', ['other', 'Index']],
])
const onButtonClick = (status) => {
let action = actions.get(status) || actions.get('default')
sendLog(action[0])
jumpTo(action[1])
}
使用 Map 对象替代普通对象具有诸多优势,主要区别体现在以下几个方面:
- 普通对象通常继承自原型链,因此始终包含一个 'prototype' 键。
- 普通对象的键只能是字符串或符号类型,而 Map 的键可以是任意类型的值。
- Map 提供了 size 属性,可以方便地获取键值对的数量;而普通对象的键值对数量无法直接通过属性获取。
接下来提升问题难度:点击按钮时,除了判断状态,还需要判断用户身份。
双重判断带来的代码膨胀问题
const onButtonClick = (status, identity) => {
if (identity == 'guest') {
if (status == 1) {
//do sth
} else if (status == 2) {
//do sth
} else if (status == 3) {
//do sth
} else if (status == 4) {
//do sth
} else if (status == 5) {
//do sth
} else {
//do sth
}
} else if (identity == 'master') {
if (status == 1) {
//do sth
} else if (status == 2) {
//do sth
} else if (status == 3) {
//do sth
} else if (status == 4) {
//do sth
} else if (status == 5) {
//do sth
} else {
//do sth
}
}
}
从上述示例可以看出,当逻辑升级为双重判断时,代码的嵌套层级和复杂度会成倍增加。
如何让代码保持简洁清晰?
这里提供一种解决方案。
字符串拼接键处理多重条件
const actions = new Map([
['guest_1', () => {}],
['guest_2', () => {}],
['guest_3', () => {}],
['guest_4', () => {}],
['guest_5', () => {}],
['master_1', () => {}],
['master_2', () => {}],
['master_3', () => {}],
['master_4', () => {}],
['master_5', () => {}],
['default', () => {}],
])
const onButtonClick = (identity, status) => {
let action = actions.get(`${identity}_${status}`) || actions.get('default')
action.call(this)
}
该方案的核心逻辑是将两个判断条件拼接成一个字符串,作为 Map 的键,查询时直接获取对应的值。当然,此处的 Map 也可以替换为普通对象。
const actions = {
guest_1: () => {},
guest_2: () => {},
//....
}
const onButtonClick = (identity, status) => {
let action = actions[`${identity}_${status}`] || actions['default']
action.call(this)
}
如果读者认为拼接字符串的方式不够直观,还有另一种解决方案:使用 Map 对象作为键。
使用 Map 对象作为键的多重判断
const actions = new Map([
[{ identity: 'guest', status: 1 }, () => {}],
[{ identity: 'guest', status: 2 }, () => {}],
//...
])
const onButtonClick = (identity, status) => {
let action = [...actions].filter(([key, value]) => key.identity == identity && key.status == status)
action.forEach(([key, value]) => value.call(this))
}
这里再次体现了 Map 与普通对象的区别:Map 允许使用任意类型的数据作为键。现在进一步增加难度:如果对于 guest 身份,状态 1 到 4 的处理逻辑完全相同,该如何处理?
最糟糕的情况会导致代码大量重复:
const actions = new Map([
[{ identity: 'guest', status: 1 }, () => {}],
[{ identity: 'guest', status: 2 }, () => {}],
[{ identity: 'guest', status: 3 }, () => {}],
[{ identity: 'guest', status: 4 }, () => {}],
[{ identity: 'guest', status: 5 }, () => {}],
//...
])
更优的方法是将处理逻辑函数分离出来:
const actions = () => {
const functionA = () => {}
const functionB = () => {}
return new Map([
[{ identity: 'guest', status: 1 }, functionA],
[{ identity: 'guest', status: 2 }, functionA],
[{ identity: 'guest', status: 3 }, functionA],
[{ identity: 'guest', status: 4 }, functionA],
[{ identity: 'guest', status: 5 }, functionB],
//...
])
}
const onButtonClick = (identity, status) => {
let action = [...actions()].filter(([key, value]) => key.identity == identity && key.status == status)
action.forEach(([key, value]) => value.call(this))
}
对于日常需求,这种写法已经足够,但函数 A 被引用了 4 次,确实略显繁琐。
如果场景更加复杂,例如身份有 3 种,状态有 10 种,需要定义 30 个处理逻辑,且其中大量逻辑相同,这显然是不可接受的。
此时可以采取以下做法:
正则表达式匹配复杂逻辑
const actions = () => {
const functionA = () => {} // 逻辑处理 A
const functionB = () => {} // 逻辑处理 B
return new Map([
[/^guest_[1-4]$/, functionA],
[/^guest_5$/, functionB],
//...
])
}
const onButtonClick = (identity, status) => {
let action = [...actions()].filter(([key, value]) => key.test(`${identity}_${status}`))
action.forEach(([key, value]) => value.call(this))
}
这时使用 Map 而非 Object 的优势便显现出来,因为可以使用正则表达式作为键。
如果需求变为:所有对 guest 的操作都需要发送日志埋点,但不同状态的 guest 可能有不同的具体逻辑,我们可以编写如下代码:
const actions = () => {
const functionA = () => {} // 逻辑处理 A
const functionB = () => {} // 逻辑处理 B
const functionC = () => {} // 发送日志 C
return new Map([
[/^guest_[1-4]$/, functionA],
[/^guest_5$/, functionB],
[/^guest_.*$/, functionC],
//...
])
}
const onButtonClick = (identity, status) => {
let action = [...actions()].filter(([key, value]) => key.test(`${identity}_${status}`))
action.forEach(([key, value]) => value.call(this))
}
这样,公共逻辑和特定逻辑可以同时执行。
总结:八种 JS 逻辑判断方式
总结
本文介绍了八种 JavaScript 逻辑判断的写法,包括:
- if-else 语句
- switch 语句
- 单一判断:存储在 Object 中
- 单一判断:存储在 Map 对象中
- 多重判断:将条件串联成一个字符串,存储在 Object 中
- 多重判断:将条件连成一个字符串,存储在 Map 对象中
- 多重判断:把条件作为对象存储在 Map 中
- 多重判断:把条件写成正则式存储在 Map 中
至此,关于 JS 逻辑判断不再局限于 if-else 和 switch 的探讨结束。更多相关 js 逻辑判断 if else switch 内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
