空值合并运算符 ??
解决的问题
考虑以下场景:
let count = 0;
alert(count || 100); // 100
count || 100
首先会检查 count
是否为一个假值,它是 0
,确实是假值。所以,||
运算的结果为第二个参数,100
。
实际上,计数 0
是一个有效值,它不应该被替换为默认值。我们更希望的情况是在变量的值为 null/undefined
时使用默认值,而空值合并运算符就解决了这个问题.
用法
如果第一个参数不是 null/undefined
,则 ??
返回第一个参数。否则,返回第二个参数
result = a ?? b // 同 result = (a !== null && a !== undefined) ? a : b
-
提供默认值
let user1; alert(user1 ?? "匿名"); // 匿名 let user2 = "John"; alert(user2 ?? "匿名"); // John
-
从一系列的值中选择出第一个非
null/undefined
的值let firstName = null; let lastName = null; let nickName = "Supercoder"; // 显示第一个已定义的值: alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
使用注意:
- 优先级:
&&
>??
=||
- 禁止将
??
运算符与&&
和||
运算符一起使用,除非使用括号明确指定了优先级
可选链 ?.
解决的问题
考虑以下场景:
let user = {};
alert(user.address.street); // TypeError: Cannot read properties of undefined (reading 'street')
由于对象user
中没有address
属性,所以自然访问不到其中的street
属性,JavaScript
则会直接报错。但实际情况是,我们更希望得到的是 undefined
(表示没有 street
属性)而不是一个错误。可选链 ?.
就是为了解决这个问题而出现的。
用法
针对result = value?.prop
,
它的含义与result = value ? value.prop : undefined
相同,也就是说:
- 如果
value
存在(既不为null
也不为undefined
),则result = value.prop
, - 否则(当
value
为undefined/null
时)则result = undefined
-
安全地访问对象的嵌套属性
let user = {}; alert( user.address?.street ); // undefined(不报错)
使用注意:
- 我们应该只将
?.
使用在一些东西可以不存在的地方,否则可能会导致代码中的错误在不应该被消除的地方消除了。比如使用user.address?.street
时,我们的意图应该是user
对象必须存在,但address
是可有可无的;而user?.address?.street
则保证了连user
都是可有可无的,但实际情况可能是user
必须存在