?? JavaScript 双问号(空值合并运算符)
一、简述
在网上浏览 JavaScript 代码时或者学习其他代码时,可能会发现有的表达式用了两个问号(??)如下所示:
let username;
console.log(username ?? "Guest");
这里的双引号称为空值合并运算符,它是 ES2020 的一个新特性,它的作用是当一个表达式是 null 或者 undefined 时为变量设置一个默认值。
二、理解实战
那么以上代码的运行结果就很明显
上述代码,由于定义了username,但并没有给username赋值,那么username的值为undefined,所以就会讲Guest打印出来。
再举个🌰,如下代码会把 firstName 变量值赋值给 username 变量。当 firstName 是 null 时,则把 “Guest” 赋值给 username。
let firstName = null;
let username = firstName ?? "Guest";
console.log(username); // "Guest"
总结来说,就是unll和undefined会被赋值??
后面给定的值
let firstName = null, gender = undefined;
let name = firstName ?? "Guest";
let genderValue = gender ?? "female";
console.log(name); // "Guest"
console.log(genderValue); // "female"
那有些好奇心比较强的同学可能会问,对于其他false类型的值,该是如何处理的,答案是取除null或undefined之外的正常赋值,看看我的实际操作吧
let age = 0, address = "", isEating = false;
let ageValue = age ?? 20;
let addressValue = address ?? "上海耀华路";
let isEatingValue = isEating ?? true;
console.log(ageValue); // 0
console.log(addressValue); // ""
console.log(isEatingValue); // false
三、对比比较
不同于 JavaScript 逻辑或(||),空值合并运算符不会在左侧操作数为假值时返回右侧操作数。其中一个例子是左侧的表达式是空字符串(“”,0,false)。
在经典JavaScript中,"",0,false
会被认为是假值,所以对于这种真实有值的情况会造成一些数据的误判,导致逻辑发生问题,从而产生了排查困难的bug 缺陷 🐞 , 也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,‘’ 或 0)时。见下面的例子。
在举个例子🌰,同样的代码,但我们将??
替换为||
,则会有不同的默认数据
let age = 0, address = "", isEating = false;
let ageValue = age || 20;
let addressValue = address || "上海耀华路";
let isEatingValue = isEating || true;
console.log(ageValue); // 20
console.log(addressValue); // "上海耀华路"
console.log(isEatingValue); // true
四、配合 || 和 && 运算符使用 ??
出于安全考虑,双问号配合 JavaScript 逻辑或(||)和逻辑与(&&)时如果没有用括号引起来是不允许的。
我们使用代码做下真实的尝试。
- 和|| 一起使用
let firstName = "John";
let lastName = "Stone";
let username = firstName || lastName ?? "Guest"; // Unexpected token '??'
console.log(username);
- 或者和&&一起使用
let firstName = "John";
let lastName = "Stone";
let username = firstName && lastName ?? "Guest"; // Error: Unexpected token '??'
console.log(username);
实际操作后,我们会发现语法不运行这么操作。这是因为 JavaScript 无法决定首先执行哪个操作符。你需要使用括号来明确告知表达式的优先级。
let firstName = null;
let lastName = undefined;
let username = (firstName || lastName) ?? "Guest";
console.log(username); // "Guest"
五、结语小段落
- JavaScript 双问号也称为空值合并运算符。这个运算符只会在左侧表达式是 null 或 undefined 时返回右侧的表达式。
- 不同于逻辑或,空值合并运算符会允许把 0 和空字符串或false作为有效的数值。
- 不要忘记在配合逻辑或/与使用时用上括号。