JavaScript的数据类型 —— Null类型

0 阅读3分钟

在 JavaScript 中,Null类型是一个基本数据类型,它只有一个唯一的值:null。通常被用来表示一个有意为之的、不指向任何对象值的空值。逻辑上讲,null值表示一个空对象指针,这也是给typeof传一个null会返回"object"的原因。

let car = null; 
console.log(typeof car); // "object",JavaScript的历史遗留 Bug,不代表null是对象
//具体原因:不同的对象在底层都表现为二进制,
//在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, 
//null 的二进制全部为 0,自然前三位也是 0,
//所以执行 typeof 值会返回 object。

在定义将来要保存对象值的变量时,建议使用null来初始化,不要使用其他值。 这样,只要检查这个变量的值是不是 null 就可以知道这个变量是否在后来被重新赋予了一个对象的引用。

if (car != null) {  
 // car 是一个对象的引用 
} 

初始化变量:预先声明一个变量,并明确表示它暂不指向任何对象。

let futureObject = null; // 表明该变量准备在将来容纳一个对象

清空对象引用:当一个对象不再需要时,将其引用设置为 null,这有助于垃圾回收机制释放内存。

let myHeavyObject = { ... }; // 一个占用大量内存的对象
// ... 使用完成后
myHeavyObject = null; // 断开引用,提示可以回收内存

函数的返回值:当函数没有找到有效结果或操作失败时,返回 null来表示"无"。

function findUser(id) {
  const user = users.find(u => u.id === id);
  return user || null; // 找到用户返回用户对象,否则返回 null
}

DOM 操作:在获取不存在的 DOM 元素时,通常会返回 null

const nonExistentElement = document.getElementById('does-not-exist');
console.log(nonExistentElement); // null

如何安全地检测与处理 null

//正确检测 null
//由于 typeof的 Bug,最可靠的方法是使用严格相等运算符(===)
if (myVar === null) {
  // 明确处理 myVar 为 null 的情况
}

//安全地访问可能为 null的属性
//在尝试访问 null(或 undefined)的属性时,JavaScript 会抛出 TypeError。
//可选链操作符(?.) :如果遇到 null或 undefined就立即停止访问,返回 undefined
let name = user?.profile?.name; // 如果 user 或 profile 为 null/undefined,name 则为 undefiend
//空值合并操作符(??) :为 null或 undefined提供一个默认值
let displayName = user?.profile?.name ?? '匿名用户'; // 如果名字为空,则显示'匿名用户'

undefined 的区别

undefined值是由null值派生而来的,在ECMA-262将它们定义为表面上相等。

console.log(null == undefined); // true

即使nullundefined有关系,它们的用途也是完全不一样的。不要显式地将变量值设置为undefined,当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个 undefined 值。Javascript 会自动将声明时没有进行初始化的变量设为 undifined

null任何时候,只要变量要保存对象,而当时又没有那个对象可保存,就要用null来填充该变量。null 不能通过 Javascript 来自动赋值,也就是说必须要我们自己手动来给某个变量赋值为 null。这样就可以保持null是空对象指针的语义,并进一步与undefined区分开来。

虽然 undefinednull在非严格相等比较(==)时结果为 true,但它们有本质的不同。

特性undefinednull
含义表示变量处于自然的、未初始化的原始状态。表示一个被人为主动赋值的空对象指针,代表"空值"。
数据类型typeof返回 "undefined"。typeof返回 "object"(这是历史遗留问题)。
严格相等undefined === null的结果为 false。
转换为数字Number(undefined)的结果是 NaN。Number(null)的结果是 0。