空值合并操作符和可选链操作符

666 阅读4分钟

空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。

空值合并操作符(??)

空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

与逻辑或操作符(||)不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。

const foo = '' ?? 'default string';
console.log(foo);
// expected output: ""

const baz = '' || 42;
console.log(baz);
// expected output: 42
  • || 返回第一个 值。
  • ?? 返回第一个 已定义的 值。

换句话说,|| 无法区分 false0空字符串 ""null/undefined。它们都一样 —— 假值(falsy values)。如果其中任何一个是||的第一个参数,那么我们将得到第二个参数作为结果。

不过在实际中,我们可能只想在变量的值为 null/undefined 时使用默认值。也就是说,当该值确实未知或未被设置时。 例如,考虑下面这种情况:

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0

height || 100 首先会检查 height 是否为一个假值,发现它确实是。 所以,结果为第二个参数,100

height ?? 100 首先会检查 height 是否为 null/undefined,发现它不是。

所以,结果为 height 的原始值,0。

如果高度 0 为有效值,则不应将其替换为默认值,所以 ?? 能够得出正确的结果。

将 ?? 直接与 AND(&&)和 OR(||)操作符组合使用是不可取的。(译者注:应当是因为空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序是未定义的)这种情况下会抛出 SyntaxError

可选链操作符

可选链操作符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined

可选链与函数调用

当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题要么因为当前用户的设备不支持该功能。

函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。

let result = someInterface.customMethod?.();

注意: 如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 TypeError 异常 (x.y is not a function).

可选链不能用于赋值

let object = {};
object?.property = 1; 
// Uncaught SyntaxError: Invalid left-hand side in assignment

可选链访问数组元素

let arrayItem = arr?.[42];

可选链和表达式

当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:

let nestedProp = obj?.['prop' + 'Name'];

总结:

空值合并操作符针对 undefinednull 这两个值,可选链式操作符(?.)也是如此。

我是南飞雁,你可以叫我飞雁,我是一名奋斗者,在实现财富自由的路上……

我喜欢分享,也喜欢思考;我有自己的人生规划和梦想;但有时也很迷茫……

我从事IT行业,研究的技术领域相对比较多而杂: PHP、MySQL、Linux、JavaScript、Node.js、NoSQL、PhotoShop、音视频处理、架构集群、网络通信、生活技巧、人生三观、做人做事读书……

我总是会在自己的公众号和掘金上写下自己的所思所想和近期要做的事,希望你关注我,我是一个奋斗者,我叫南飞雁