在平时开中,涉及到逻辑判断的时候,大多数情况我们一般采用if,偶尔使用switch。但是,条件较为多的情况下(5种以上),能使用switch尽可能使用switch。
事实证明,除了代码可读性,switch 的运行速度是比 if else 更快的。
相比较于 if else ,switch 的实现采取了branch table 索引来进行优化(深入了解可以看这里:en.wikipedia.org/wiki/Switch… ,而且 switch 语句比较时使用是全等操作符,不会发生类型转换的损耗。
上例子:
if
const start = new Date().getTime()
const a = 6
for(let i = 0; i < 9999999; i++) {
if (a === 1) {
} else if (a === 2) {
} else if (a === 3) {
} else if (a === 4) {
} else if (a === 5) {
} else {
}
}
const end = new Date().getTime()
console.log(end - start)
// 运行时间在5000毫秒左右
复制代码
switch
const start = new Date().getTime()
const a = 6
for (let i = 0; i < 9999999; i++) {
swich(a) {
case 1: ;break;
case 2: ;break;
case 3: ;break;
case 4: ;break;
case 5: ;break;
default : ;
}
}
const end = new Date().getTime()
console.log(end - start)
// 运行在1000秒左右
复制代码
如果我们把条件直接就放在第一个,看看会发生什么
const a = 1; // 把这个改为 1
for(let i = 0; i < 9999999; i++) {
if (a == 1) { // 走到这里就满足了条件
} else if (a == 2) {
} else if (a == 3) {
} else if (a == 4) {
} else if (a == 5) {
} else {
}
}
// 现在它的执行时间和 switch 执行时间无限接近了,在1100左右
// 如果a = 2 那么执行条件会在2200毫秒左右,
因此,在 if-else 语句中,它的条件语句应该以 **最大概率出现到最小概率出现依次排列。**
复制代码
在我们使用if时,应减少判断次数,使用嵌套语句
假设 a 的值出现的概率都差不多,那么可以减少外层的 if-else,而是把它拆开,分成几块来判断。
const start = new Date().getTime();
const a = 6;
for(let i = 0; i < 9999999; i++) {
if (a <= 3) {
if (a == 1) {
} else if (a == 2) {
} else {
}
} else {
if (a == 4) {
} else if (a == 5) {
} else {
}
}
}
const end = new Date().getTime()
console.log(end - start)
// 现在它的执行时间在 3200 毫秒左右波动
复制代码
显然,这样的写法,可读性大家可想而知。在既能使用if和switch且判断条件5种以上,switch写法与性能上更优秀。
那么是否还有其他写法呢?
其实在项目中,优化条件语句的最好办法还是避免使用 if-else 和 switch 语句,而是通过数组和对象来查询,也就是查找表(lookup Tables)。
我实际开发中的一个例子:通过判断条件,跳转到不同的页面
function getUrl(type) {
if(type = 'a') {
return '/page/index/a'
}
else if(type = 'b') {
return '/page/index/b'
}
else if(type = 'c') {
return '/page/index/c'
}
else if(type = 'd') {
return '/page/index/d'
}
else {
return '/page/index/e'
}
}
const url = getUrl(tupe)
wx.nevigateTo({
url : url
})
复制代码
对象写法
const obj = {
a : '/page/index/a',
b : '/page/index/b',
c : '/page/index/c',
d : '/page/index/d',
default: '/page/index/e'
}
const url = obj[type] || action['default']
wx.nevigateTo({
url : url
})
复制代码
这种方法的巧妙之处在于,它把判断条件作为对象的属性名,把处理逻辑作为对象的属性值。在点击按钮的时候,这种方法特别适用于单项条件判断的情况,即通过对象属性查找的方式进行逻辑判断。
那么还有其他方法呢? 答案是肯定的!
const maps = new Map([
[a : '/page/index/a'],
[b : '/page/index/b'],
[c : '/page/index/c'],
[d : '/page/index/d'],
[default: '/page/index/e'],
])
const url = maps.get(type)
wx.nevigateTo({
url : url
})
复制代码
**使用 Map 代替 Object 有很多优点,Map 对象和普通对象有的区别是:
- 一个对象通常有自己的原型,所以一个对象总是有一个“prototype”键
- 对象的键只能是一个字符串或符号,但 Map 的键可以是任何值
- 你可以通过使用 size 属性很容易得到 Map 中的键值对的数量,而一个对象中的键值对数量不能直接获取
总结:
1.switch 性能高于 if-else
2.项目中尽量避免使用 switch 和 if else,使用查找表代替
3.new Map是ES6写法,比起传统对象具有明显的优点
另外,WeakMap结构与Map结构类似,也是用于生成键值对的集合。
顺便简单提下:
-
WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
-
WeakMap的键名所指向的对象,不计入垃圾回收机制。
详细可以查找ES6之Set,Mep