?. 和 ?? 运算符 判断undefined
一、?.
链判断运算符
有时候我们想要获取对象中的一个值,例如
1const firstName = user.profile.name.firstName
profile可能为undefined
,name可能为null
的时候,我们需要做如下判断
1
2
3
4const firstName=user&& user.profile&& user.profile.name&& user.profile.name.firstName
我们可以使用lodash库来简化这些:
1
2import { get } from 'lodash' const firstName = get(user, ['profile', 'name', 'firstName'])
1、es6中为本机提供了解决方案
1const firstName = user?.profile?.name?.firstName
?.
运算符视为一个短路,if the expression up until this point is null or undefined, then the whole expression evaluates to undefined
。如果?.
后面为null
或undefined
,阻断后续执行,整个表达式的结果为undefined
。
1
2
3
4
5
6const read =>user=>user.profile?.name?.firstName read() // <- Error 因为user为undefined read({}) // <- undefined read({profile: {}}) // <- undefined read({ profile: { name: { firstName: 'Bob' } } }) // <- 'Bob'
2、?.
可以出现在任何表达式之后,函数和数组
1
2
3
4
5let a = null // 函数调用 a?.() // <- undefined 不会报错 // 数组 a?.[0] // <- undefined 不会报错
1
2
3
4
5
6
7delete a?.b // 等同于 a == null ? undefined : delete a.b (a?.b).c // 等同于 (a == null ? undefined : a.b).c
3、以下情况会报错
1
2
3
4
5
6
7
8
9
10
11// 构造函数 new a?.() new a?.b() // 链判断运算符的右侧有模板字符串 a?.`{b}` a?.b`{c}` // 链判断运算符的左侧是 super super?.() super?.foo // 链运算符用于赋值运算符左侧 a?.b = c
二、??
是ES2020 引入了一个新的 Null 判断运算符
为value赋值的时候,如果curValue为null的时候,就默认为defautValue
1value= curValue || defautValue
这样写会有问题,如果curValue=false或者0时,会出现错误的赋值。大家可以这样写:
1value= curValue ?? defautValue
只有运算符左侧的值为null或undefined时,才会返回右侧的值。
1、优先级
??
有一个运算优先级问题,它与&&和||的优先级孰高孰低。现在的规则是,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错
1
2
3
4
5// 报错 lhs && middle ?? rhs lhs ?? middle && rhs lhs || middle ?? rhs lhs ?? middle || rhs
1
2
3
4
5
6
7
8
9// 正确 (lhs && middle) ?? rhs; lhs && (middle ?? rhs); (lhs ?? middle) && rhs; lhs ?? (middle && rhs); (lhs || middle) ?? rhs; lhs || (middle ?? rhs); (lhs ?? middle) || rhs; lhs ?? (middle || rhs);