ES2016 新增了一个指数运算符(**)。
2 ** 2 // 4
2 ** 3 // 8
在写代码的时候,通常读取对象内部的某个属性,往往需要判断一下,属性的上层对象是否存在。比如,读取 user.name 这个属性,安全的写法是写成下面这样。
// 如果不存在 user 对象将报错
const firstName = user.name || 'default';
// 正确的写法
const firstName = (user && user.name) || 'default';
三元运算符 ?:
也常用于判断对象是否存在。
const firstName = user ? user.name : 'default'
上面例子中,必须先判断 user 是否存在,才能读取 user.name。
这样的层层判断非常麻烦,因此 ES2020 引入了“链判断运算符” ?.
,简化上面的写法。
const firstName = user?.name || 'default';
上面代码使用了?.运算符,直接在链式调用的时候判断,左侧的对象是否为 null 或 undefined。如果是的,就不再往下运算,而是返回 undefined。
下面是判断对象方法是否存在,如果存在就立即执行的例子。
iterator.return?.()
上面代码中,iterator.return 如果有定义,就会调用该方法,否则 iterator.return 直接返回undefined,不再执行 ?.
后面的部分。
对于那些可能没有实现的方法,这个运算符尤其有用。
本质上,?.
运算符相当于一种短路机制,只要不满足条件,就不再往下执行。
读取对象属性的时候,如果某个属性的值是 null 或 undefined,有时候需要为它们指定默认值。常见做法是通过 ||
运算符指定默认值。
const firstName = user.name || 'default';
上面的代码都通过 ||
运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为 null 或 undefined,默认值就会生效,但是属性的值如果为空字符串或 false 或 0 ,默认值也会生效。
为了避免这种情况,ES2020 引入了一个新的 Null 判断运算符 ??
。它的行为类似 ||
,但是只有运算符左侧的值为 null 或 undefined 时,才会返回右侧的值。
const firstName = user.name ?? 'default';
上面代码中,默认值只有在左侧属性值为 null 或 undefined 时,才会生效。
这个运算符的一个目的,就是跟链判断运算符 ?.
配合使用,为 null 或 undefined 的值设置默认值。
const firstName = user?.name ?? 'default';
这个运算符很适合判断函数参数是否赋值。
function Component(props) {
props.enabled = props.enabled ?? true;
// …
}
ES2021 引入了三个新的逻辑赋值运算符,将逻辑运算符与赋值运算符进行结合。
// 或赋值运算符
x ||= y
// 等同于
x || (x = y)
// 与赋值运算符
x &&= y
// 等同于
x && (x = y)
// Null 赋值运算符
x ??= y
// 等同于
x ?? (x = y)
它们的一个用途是,为变量或属性设置默认值。
// 老的写法
user.id = user.id || 1;
// 新的写法
user.id ||= 1;
上面示例中,user.id 属性如果不存在,则设为 1,新的写法比老的写法更紧凑一些。
下面是另一个例子。
function Component(props) {
props.enabled ??= true;
// …
}
设置默认值非常便捷。