JS逻辑判断不仅仅是if或switch,还有更优写法

在平时开中,涉及到逻辑判断的时候,大多数情况我们一般采用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结构类似,也是用于生成键值对的集合。

顺便简单提下:

  1. WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。

  2. WeakMap的键名所指向的对象,不计入垃圾回收机制。

详细可以查找ES6之Set,Mep

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享