与许多其他语言不同,JavaScript 中有两种不同的东西,用来表示一个(有意义的)值不存在。它们就是null和undefined。
原始值null用来有意地表示变量的“空值”。在其他语言中,类似的构造可能只用于(缺失的)对象或指针类型。而在 JavaScript 中,null通常可以表示任何类型的空值。
let name = null;
// name is intentionally set to "empty" because it is not
// available
你可以使用严格相等运算符===来检查一个变量是否为 null。尽管null是原始值,typeof运算符出于历史原因会“错误地”返回object。这意味着不能只靠它来判断一个变量是否为 null。
let name = null;
name === null;
// => true
// Pitfall:
typeof name;
// => 'object'
没有被赋值的变量,其类型为
undefined。1
也就是说,null表示一个空值(但仍然是一个值),而undefined表示完全没有值。🤯
undefined会出现在不同的场景中。
undefined。undefined。undefined。undefined,除非该实参有默认值。let name;
console.log(name);
// => undefined
let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined
function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
你可以使用严格相等运算符===或typeof运算符来检查一个变量是否为 undefined。
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
不建议手动把undefined赋值给变量,请始终改用null,以清楚地表明你是有意设置一个空值。
如上所述,在 JavaScript 中访问对象里不存在的键会返回undefined。但如果你试图获取一个嵌套的值,而它的父键并不存在,那么对嵌套键的求值就会在undefined上进行,从而导致TypeError: Cannot read property ... of undefined。理论上,你总是需要先确认父键存在,才能尝试获取嵌套键。过去常用逻辑与运算符&&来做这件事,但对于嵌套很深的值,这会让表达式变得非常冗长。
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
为了解决这个问题,可选链在 2020 年被加入了语言规范。使用可选链运算符?.,你可以确保只有在父键不是null或undefined时,JavaScript 才会尝试访问嵌套键。否则返回undefined。
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.residence;
// => undefined
obj.address.zipCode;
// => undefined
obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined
obj.residence?.street;
// => undefined
obj.residence?.street?.number;
// => undefined
有时你希望在一个变量为 null 或 undefined 时应用一个默认值。过去常用三元运算符?,或者利用逻辑或运算符||的惰性求值来实现。这种做法的缺点是:只要变量是假值(例如''或0),默认值就会被应用,而不只是在它为 null 或 undefined 时。这很容易导致意外的结果。
let amount = null;
amount = amount || 1;
// => 1
amount = 0;
amount = amount || 1;
// => 1
amount = 0;
amount ? amount : 1;
// => 1
为了解决这个问题,空值合并运算符??被引入了。和可选链一样,它也是在 2020 年被加入语言规范的。空值合并运算符??只有在左侧操作数为null或undefined时才返回右侧操作数。否则就返回左侧操作数。这样,就可以更精确地应用默认值了。
let amount = null;
amount = amount ?? 1;
// => 1
amount = 0;
amount = amount ?? 1;
// => 0
[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (访问于 2021 年 6 月 4 日)。