11.undefined和null

许多编程语言都有一个名为null的“非值”。它表示变量当前未指向对象。例如,尚未初始化时。相比之下,JavaScript 有两个:undefined和null。

11.1 undefinednull

两个值都非常相似,并且通常可互换使用。因此它们的区别是微妙的。语言本身具有以下区别:

  • undefined表示“未初始化”(例如变量)或“不存在”(例如对象的属性)。
  • null表示“故意没有任何对象值”(参考语言规范)。

程序员可以做出以下区分:

  • undefined是语言使用的非值(当某些内容未初始化时)。
  • null表示“明确关闭”。也就是说,它有助于实现一种类型,既包含有意义的值又包含代表“无意义的值”的元值。这种类型在函数式编程中称为可选类型可能类型

11.2 undefinednull的位置

以下小节描述了undefinednull在语言中的位置。我们将遇到几种机制,本书稍后将对此进行更详细的解释。

11.2.1 undefined的位置

未初始化的变量myVar

let myVar;
assert.equal(myVar, undefined);

未提供的参数x

function func(x) {
  return x;
}
assert.equal(func(), undefined);

缺失属性.unknownProp

const obj = {};
assert.equal(obj.unknownProp, undefined);

如果没有通过return运算符显式指定函数的结果,JavaScript 会为您返回undefined

function func() {}
assert.equal(func(), undefined);

11.2.2 null的位置

对象的原型是一个对象,或者在原型链的末尾,是nullObject.prototype没有原型:

> Object.getPrototypeOf(Object.prototype)
null

如果将正则表达式(例如/a/)与字符串(例如'x')匹配,则可以获得具有匹配数据的对象(如果匹配成功)或null(如果匹配失败):

> /a/.exec('x')
null

JSON 数据格式不支持undefined,仅支持null

> JSON.stringify({a: undefined, b: null})
'{"b":null}'

11.3 检查undefinednull

检查:x有值吗?

if (x === null) ···
if (x === undefined) ···

xundefined还是null

if (x !== undefined && x !== null) {
  // ···
}
if (x) { // truthy?
  // x is neither: undefined, null, false, 0, NaN, ''
}

真值 的意思是“如果强制转换为布尔值则为true”。假值 的意思是“如果强制转换为布尔值则为false”。在 12.布尔值 的章节中正确解释了这两个概念。

11.4 undefinednull没有属性

undefinednull是两个唯一的 JavaScript 值,如果您尝试读取属性,则会获得异常。为了探索这种现象,让我们使用以下函数,它读取(“获取”)属性.foo并返回结果。

function getFoo(x) {
  return x.foo;
}

如果我们将getFoo()应用于各种值,我们可以看到它只对undefinednull失败:

> getFoo(undefined)
TypeError: Cannot read property 'foo' of undefined
> getFoo(null)
TypeError: Cannot read property 'foo' of null
> getFoo(true)
undefined
> getFoo({})
undefined

11.5 undefinednull的历史

在 Java(它激发了 JavaScript 的许多方面)中,初始化值取决于变量的静态类型:

  • 具有对象类型的变量用null初始化。
  • 每个原始类型都有自己的初始化值。例如,int变量用0初始化。

在 JavaScript 中,每个变量都可以包含对象值和原始值。因此,如果null表示“不是对象”,JavaScript 还需要一个初始化值,这意味着“既不是对象也不是原始值”。初始化值为undefined