许多编程语言都有一个名为null的“非值”。它表示变量当前未指向对象。例如,尚未初始化时。相比之下,JavaScript 有两个:undefined和null。
11.1 undefined
与null
两个值都非常相似,并且通常可互换使用。因此它们的区别是微妙的。语言本身具有以下区别:
undefined
表示“未初始化”(例如变量)或“不存在”(例如对象的属性)。null
表示“故意没有任何对象值”(参考语言规范)。
程序员可以做出以下区分:
undefined
是语言使用的非值(当某些内容未初始化时)。null
表示“明确关闭”。也就是说,它有助于实现一种类型,既包含有意义的值又包含代表“无意义的值”的元值。这种类型在函数式编程中称为可选类型 或可能类型 。
11.2 undefined
和null
的位置
以下小节描述了undefined
和null
在语言中的位置。我们将遇到几种机制,本书稍后将对此进行更详细的解释。
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
的位置
对象的原型是一个对象,或者在原型链的末尾,是null
。 Object.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 检查undefined
或null
检查:x
有值吗?
if (x === null) ···
if (x === undefined) ···
x
是undefined
还是null
?
if (x !== undefined && x !== null) {
// ···
}
if (x) { // truthy?
// x is neither: undefined, null, false, 0, NaN, ''
}
真值 的意思是“如果强制转换为布尔值则为true
”。假值 的意思是“如果强制转换为布尔值则为false
”。在 12.布尔值 的章节中正确解释了这两个概念。
11.4 undefined
和null
没有属性
undefined
和null
是两个唯一的 JavaScript 值,如果您尝试读取属性,则会获得异常。为了探索这种现象,让我们使用以下函数,它读取(“获取”)属性.foo
并返回结果。
function getFoo(x) {
return x.foo;
}
如果我们将getFoo()
应用于各种值,我们可以看到它只对undefined
和null
失败:
> 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 undefined
和null
的历史
在 Java(它激发了 JavaScript 的许多方面)中,初始化值取决于变量的静态类型:
- 具有对象类型的变量用
null
初始化。 - 每个原始类型都有自己的初始化值。例如,
int
变量用0
初始化。
在 JavaScript 中,每个变量都可以包含对象值和原始值。因此,如果null
表示“不是对象”,JavaScript 还需要一个初始化值,这意味着“既不是对象也不是原始值”。初始化值为undefined
。