代码简洁之道(判断篇)

你说的曾经没有我的故事 提交于 2020-02-20 10:18:48

摘自:https://www.cnblogs.com/guangzan/p/12222370.html

 代码简洁之道(判断篇)

 

第一个例子

copy
 
if (state === 1) {
 
return true
 
} else if (state === 2) {
 
return true
 
} else if (state === 3) {
 
return true
 
} else if (state === 4){
 
return true
 
} else {
 
return false
 
}

你首先想到的可能是 使用 switch case, 我们使用 switch case 来改写它:

copy
 
switch (state) {
 
case 1: return true
 
break;
 
case 2: return true
 
break;
 
case 3: return true
 
break
 
case 4: return true
 
break
 
default: return false
 
break
 
}

看起来有些条理了, 但我们应对这类情况,可以将他进一步优化,观察发现:

  • 都是判断 state
  • 判断后都做了相同的事情 (return true)

我们用 Array.includes 来优化它:

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

  • 参数一:必须。需要查找的元素值。
  • 参数二:可选。从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜索。默认为 0。
copy
 
const states = [1, 2, 3, 4]
 
if (states.includes(state) {
 
return true
 
}

这样是不是更简单,代码量也更少了,同时也方便管理 states, 因为现在所有 state 都被加到 一个数组 (states) 了。

如果不是做相同的事情呢(即每一种状态下我们需要做不同的事情)?例如下面这种情况:

copy
 
if (state === 1) {
 
// do something
 
} else if (state === 2) {
 
// do something
 
} else if (state === 3) {
 
// do something
 
} else if (state === 4){
 
// do something
 
} else {
 
// do something
 
}

我们可以使用对象来优化它:

copy
 
const actions = {
 
1: () => { /*do something*/ },
 
2: () => { /*do something*/ },
 
3: () => { /*do something*/ },
 
4: () => { /*do something*/ },
 
'default': () => { /*do something*/ }
 
}
   
 
actions[state]() || actions['default']();
  • 可读性更高
  • 更易于维护

原理很简单,只需要通过对象的 key 找到对象的值, 而对应的值又是一个 func, 同时来执行它就可以了。

第二个例子

copy
 
if (type === 'firstType') {
 
if (state === 1) {/*do something*/
 
// do something
 
} else if (state === 2) {
 
// do something
 
} else if (state === 3) {
 
// do something
 
} else if (state === 4){
 
// do something
 
} else {
 
// do something
 
}
 
} else if (type === 'secondType') {
 
if (state === 1) {
 
// do something
 
} else if (state === 2) {
 
// do something
 
} else if (state === 3) {
 
// do something
 
} else if (state === 4){
 
// do something
 
} else {
 
// do something
 
}
 
}

观察上面的代码,发现外层又套了一层判断,这在日常业务中也是十分常见的,例如一个 APP 需要区分不同身份,或者多端应用中。。。

仿照上面的例子稍加变动我们就能将它优化:

copy
 
const actions = {
 
'firstType_1': ()=>{ /*do something*/ }],
 
'firstType_2': ()=>{ /*do something*/ }],
 
'firstType_3': ()=>{ /*do something*/ }],
 
'firstType_4': ()=>{ /*do something*/ }],
 
'secondType_1': ()=>{ /*do something*/ }],
 
'secondType_2': ()=>{ /*do something*/ }],
 
'secondType_3': ()=>{ /*do something*/ }],
 
'secondType_4': ()=>{ /*do something*/ }],
 
'default': ()=>{ /*do something*/ }]
 
}
   
 
const action = actions[`${type}_${state}`] || actions['default']

我们给对象的 key 设置为一个字符串,字符串由两个条件通过 _ (当然你可以随意) 链接在一起,它所对应的值依然是一个 func 。
同时用两个变量通过模板字符串的形式链接在一起,实现与上个例子相同的效果。

我们还可以使用 Map 来优化它:

copy
 
const actions = new Map([
 
['firstType_1', ()=>{ /*do something*/ }],
 
['firstType_2', ()=>{ /*do something*/ }],
 
['firstType_3', ()=>{ /*do something*/ }],
 
['firstType_4', ()=>{ /*do something*/ }],
 
['secondType_1', ()=>{ /*do something*/ }],
 
['secondType_2', ()=>{ /*do something*/ }],
 
['secondType_3', ()=>{ /*do something*/ }],
 
['secondType_4', ()=>{ /*do something*/ }],
 
['default', ()=>{ /*do something*/ }]
 
])
   
 
const action = actions.get(`${type}_${state}`) || actions.get('default')

Map 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

原理与上个是一样的,不过是将对象的形式改为了 Map 的形式,发现这样稍微复杂了一些,但是我们可以用它来处理更复杂的情况。

我们假设 firstType 中 state 为 1-3 都做相同的事,那么可以这样写:

copy
 
const actions = new Map([
 
['/^firstType_[1-3]$/', ()=>{ /*do something*/ }],
 
['firstType_4', ()=>{ /*do something*/ }],
 
// ...
 
['default', ()=>{ /*do something*/ }]
 
])

很显然使用正则表达式能够减少重复的代码, 也能带来更多可能性,处理更复杂的情况。

如果对应的方法中出现大量逻辑代码,那么我们可以将 actions 封装为一个函数。进一步来优化它,:

copy
 
const actions = () => {
 
const fn1 = () => {}
 
const fn2 = () => {}
 
return new Map([
 
['/^firstType_[1-3]$/', fn1],
 
['firstType_4', fn2],
 
// ...
 
])
 
}

这样做的好处是把对应的逻辑抽离出来,更加方便日后维护,条理更加清晰。

参考资料:

 
分类: JavaScriptothers
标签: 代码优化
 
 

第一个例子

copy
 
if (state === 1) {
 
return true
 
} else if (state === 2) {
 
return true
 
} else if (state === 3) {
 
return true
 
} else if (state === 4){
 
return true
 
} else {
 
return false
 
}

你首先想到的可能是 使用 switch case, 我们使用 switch case 来改写它:

copy
 
switch (state) {
 
case 1: return true
 
break;
 
case 2: return true
 
break;
 
case 3: return true
 
break
 
case 4: return true
 
break
 
default: return false
 
break
 
}

看起来有些条理了, 但我们应对这类情况,可以将他进一步优化,观察发现:

  • 都是判断 state
  • 判断后都做了相同的事情 (return true)

我们用 Array.includes 来优化它:

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

  • 参数一:必须。需要查找的元素值。
  • 参数二:可选。从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜索。默认为 0。
copy
 
const states = [1, 2, 3, 4]
 
if (states.includes(state) {
 
return true
 
}

这样是不是更简单,代码量也更少了,同时也方便管理 states, 因为现在所有 state 都被加到 一个数组 (states) 了。

如果不是做相同的事情呢(即每一种状态下我们需要做不同的事情)?例如下面这种情况:

copy
 
if (state === 1) {
 
// do something
 
} else if (state === 2) {
 
// do something
 
} else if (state === 3) {
 
// do something
 
} else if (state === 4){
 
// do something
 
} else {
 
// do something
 
}

我们可以使用对象来优化它:

copy
 
const actions = {
 
1: () => { /*do something*/ },
 
2: () => { /*do something*/ },
 
3: () => { /*do something*/ },
 
4: () => { /*do something*/ },
 
'default': () => { /*do something*/ }
 
}
   
 
actions[state]() || actions['default']();
  • 可读性更高
  • 更易于维护

原理很简单,只需要通过对象的 key 找到对象的值, 而对应的值又是一个 func, 同时来执行它就可以了。

第二个例子

copy
 
if (type === 'firstType') {
 
if (state === 1) {/*do something*/
 
// do something
 
} else if (state === 2) {
 
// do something
 
} else if (state === 3) {
 
// do something
 
} else if (state === 4){
 
// do something
 
} else {
 
// do something
 
}
 
} else if (type === 'secondType') {
 
if (state === 1) {
 
// do something
 
} else if (state === 2) {
 
// do something
 
} else if (state === 3) {
 
// do something
 
} else if (state === 4){
 
// do something
 
} else {
 
// do something
 
}
 
}

观察上面的代码,发现外层又套了一层判断,这在日常业务中也是十分常见的,例如一个 APP 需要区分不同身份,或者多端应用中。。。

仿照上面的例子稍加变动我们就能将它优化:

copy
 
const actions = {
 
'firstType_1': ()=>{ /*do something*/ }],
 
'firstType_2': ()=>{ /*do something*/ }],
 
'firstType_3': ()=>{ /*do something*/ }],
 
'firstType_4': ()=>{ /*do something*/ }],
 
'secondType_1': ()=>{ /*do something*/ }],
 
'secondType_2': ()=>{ /*do something*/ }],
 
'secondType_3': ()=>{ /*do something*/ }],
 
'secondType_4': ()=>{ /*do something*/ }],
 
'default': ()=>{ /*do something*/ }]
 
}
   
 
const action = actions[`${type}_${state}`] || actions['default']

我们给对象的 key 设置为一个字符串,字符串由两个条件通过 _ (当然你可以随意) 链接在一起,它所对应的值依然是一个 func 。
同时用两个变量通过模板字符串的形式链接在一起,实现与上个例子相同的效果。

我们还可以使用 Map 来优化它:

copy
 
const actions = new Map([
 
['firstType_1', ()=>{ /*do something*/ }],
 
['firstType_2', ()=>{ /*do something*/ }],
 
['firstType_3', ()=>{ /*do something*/ }],
 
['firstType_4', ()=>{ /*do something*/ }],
 
['secondType_1', ()=>{ /*do something*/ }],
 
['secondType_2', ()=>{ /*do something*/ }],
 
['secondType_3', ()=>{ /*do something*/ }],
 
['secondType_4', ()=>{ /*do something*/ }],
 
['default', ()=>{ /*do something*/ }]
 
])
   
 
const action = actions.get(`${type}_${state}`) || actions.get('default')

Map 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

原理与上个是一样的,不过是将对象的形式改为了 Map 的形式,发现这样稍微复杂了一些,但是我们可以用它来处理更复杂的情况。

我们假设 firstType 中 state 为 1-3 都做相同的事,那么可以这样写:

copy
 
const actions = new Map([
 
['/^firstType_[1-3]$/', ()=>{ /*do something*/ }],
 
['firstType_4', ()=>{ /*do something*/ }],
 
// ...
 
['default', ()=>{ /*do something*/ }]
 
])

很显然使用正则表达式能够减少重复的代码, 也能带来更多可能性,处理更复杂的情况。

如果对应的方法中出现大量逻辑代码,那么我们可以将 actions 封装为一个函数。进一步来优化它,:

copy
 
const actions = () => {
 
const fn1 = () => {}
 
const fn2 = () => {}
 
return new Map([
 
['/^firstType_[1-3]$/', fn1],
 
['firstType_4', fn2],
 
// ...
 
])
 
}

这样做的好处是把对应的逻辑抽离出来,更加方便日后维护,条理更加清晰。

参考资料:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!