Javascript中null、NaN、undefined区别(JS空值、Javascript空值)(?.链操作符)

概述

JavaScript中的nullundefinedNaN代表了不同类型的"空"或"无效"状态,理解它们的区别对于编写健壮的代码至关重要。

null的本质

null代表一个空对象指针,是一个有意的空值。这个值的特殊之处在于其类型检查结果:

const obj = null;
console.log(typeof obj); // "object"

这个结果源于JavaScript的历史遗留问题 - 在最初的JavaScript实现中,values were represented as a type tag and a value, with the type tag for objects being 0。

undefined的两面性

系统层面的undefined

当一个变量被声明但未被初始化时,会得到undefined

let unassigned;
console.log(unassigned); // undefined

function fn() {
    // 没有返回值的函数隐式返回undefined
}
console.log(fn()); // undefined

开发者层面的undefined

对象中访问不存在的属性会返回undefined

const obj = {name: 'example'};
console.log(obj.age); // undefined

NaN的特殊性

数值运算的异常标识

NaN产生于无效的数学运算:

console.log(Math.sqrt(-1)); // NaN
console.log(0/0); // NaN

NaN的独特比较行为

NaN是JavaScript中唯一一个不等于自身的值:

console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true

深入比较

类型比较

console.log(typeof null);      // "object"
console.log(typeof undefined); // "undefined"
console.log(typeof NaN);       // "number"

相等性比较

// 宽松相等
console.log(null == undefined); // true
console.log(null == 0);        // false
console.log(undefined == 0);    // false

// 严格相等
console.log(null === undefined); // false

实践建议

变量初始化

初始化对象类型变量时,建议使用null

let userProfile = null; // 表明这里将来会是一个对象

错误检测

检测无效数值运算时,使用专门的方法:

// 不推荐
if (result === NaN) // 永远为false

// 推荐
if (Number.isNaN(result))

属性检查(链操作符)

检查对象属性时,使用可选链操作符:

const user = {};
// 旧方式
console.log(user && user.address && user.address.street);
// 现代方式
console.log(user?.address?.street); // undefined

性能考虑

在条件判断中,直接使用nullundefined作为条件会被转换为false,而不需要额外的类型转换,这在性能上是有优势的。然而,NaN的检测需要特殊处理,可能带来轻微的性能开销。

通过深入理解这些特殊值的行为和使用场景,可以编写出更加健壮和可维护的JavaScript代码。