欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【JS】你不知道的ES6 (一)

程序员文章站 2022-07-13 08:42:12
...

【JS】你不知道的ES6 (一)

链判断运算符

ES5 我们判断一个深层级的对象是否有某一个 key 需要一层一层去判断,现在我们可以通过?.的方式去获取

// es5
// 错误的写法(当某一个key不存在undefined.key就会代码报错)
const  firstName = message.body.user.firstName;

// 正确的写法
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';

// es6
const firstName = message?.body?.user?.firstName || 'default';

链判断运算符的三种用法,?. 运算符相当于一种短路机制,只要不满足条件,就不再往下执行

  1. obj?.prop // 对象属性
  2. obj?.[expr] // 对象属性
  3. func?.(...args) // 函数或对象方法的调用

Null 运算判断符

读取对象属性的时候,如果某个属性的值是 nullundefined,有时候需要为它们指定默认值,常见做法是通过 || 运算符指定默认值

(null || undefined) ?? 1  // => 1

?? 运算符没有 || 健壮,只针对 nullundefined 进行默认值设置,且存在运算优先级问题,与其他一元操作符配合使用需要用括号表明优先级

Map 对象

Map 对象在实际的业务场景中,多用于抽离复杂逻辑判断,在一元条件判断无法满足的情况下

将判断条件作为对象的属性名,将处理逻辑作为对象的属性值,在按钮点击的时候,通过对象属性查找的方式来进行逻辑判断, 时间复杂度 o(n) to o(1)

const actions = {
  '1': ['processing','IndexPage'],
  '2': ['fail','FailPage'],
  '3': ['fail','FailPage'],
  '4': ['success','SuccessPage'],
  '5': ['cancel','CancelPage'],
  'default': ['other','Index'],
}
/**
 * 按钮点击事件
 * @param {number} status 活动状态:1开团进行中 2开团失败 3 商品售罄 4 开团成功 5 系统取消
 */
const onButtonClick = status => {
  const action = actions[status] || actions['default']
  const [logName, pageName] = action

  sendLog(logName); jumpTo(pageName)
}

ES6 Map 写法,且接受任何类型的作为索引包括对象,.set(key, value)

const actions = new Map([
  [1, ['processing','IndexPage']],
  [2, ['fail','FailPage']],
  [3, ['fail','FailPage']],
  [4, ['success','SuccessPage']],
  [5, ['cancel','CancelPage']],
  ['default', ['other','Index']]
])

/**
 * 按钮点击事件
 * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
 */
const onButtonClick = (status)=>{
  const action = actions.get(status) || actions.get('default')
  
  sendLog(action[0]); jumpTo(action[1])
}

以对象作为键,从而满足复杂条件,可以设想以下业务场景,选购一件商品(红色,xl,vip),以上条件满足则执行下一步,ES5可以通过 'red|1|vip': function 作为替代方案

const actions = 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 */}],
  //...
])

再优化下,将处理逻辑函数进行缓存,将 status 进行二分法查找

const actions = ()=>{
  const functionA = ()=>{/*do sth*/}
  const functionB = ()=>{/*do sth*/}
  return new Map([
    [{identity:'guest',status:1},functionA],
    [{identity:'guest',status:2},functionA],
    [{identity:'guest',status:3},functionA],
    [{identity:'guest',status:4},functionB],
    [{identity:'guest',status:5},functionB],
    //...
  ])
}

const onButtonClick = (identity,status)=>{
  const action = [...actions()].filter(([key,value])=>(key.identity == identity && key.status == status))
  action.forEach(([key,value])=>value.call(this))
}

或者通过正则作为判断条件,利用数组循环的特性,符合正则条件的逻辑都会被执行,那就可以同时执行公共逻辑和单独逻辑

[/^guest_[1-4]$/, functionA],
[/^guest_5$/, functionB],
[/^guest_.*$/, functionC],

解构赋值

剔除对象或对象不需要的属性的值,解构套娃和重命名的用法自行百度…

const obj = {
    name: 'detanx',
    age: 24,
    height: 180
}
// 剔除height
const { height, ...otherObj } = obj;
// otherObj => {name: 'detanx', age: 24}

利用参数默认值的特性,引用解构赋值的其他变量

let [x = 1, y = x] = [2];    // => x=2; y=2