1. Undefined

1. 通用知识

在计算机编程中,undefined 值是表达式没得到正确值的情况,尽管它在语法上是正确的。undefined 值和空字符串、布尔值 false 以及其它已经定义的空值是不一样的。

在有些编程语言中,对 undefined 值的使用可能会导致异常或未定义行为,但在另一些语言中,undefined 值可能发生在正常的可预测的程序执行过程中。

动态类型语言通常会显式处理 undefined 值。动态类型检查是在运行时验证程序类型安全的过程,它的实现通常是把每个运行时对象和包含其类型信息的类型标记相关联,此运行时类型信息(RTTI, Runtime Type Information)还可以用来实现动态调度、后期绑定(或动态绑定)、向下转换(或类型细化)以及反射等功能。

2. 原始值

Undefined 类型只有一个值,就是 undefined。

任何尚未赋值的变量都具有 undefined 值。

未声明的变量,类型是 Undefined,取值时会报错。如下:

typeof foo === 'undefined';  // true
console.log(foo);  // ReferenceError: foo is not defined

已声明但尚未赋值的变量,类型是 Undefined,值是 undefined。如下:

let foo;
typeof foo === 'undefined';  // true
console.log(foo);            // undefined

在实际编程中,我们通常不会将一个变量赋值为 undefined,这样就可以保证所有值是 undefined 的变量都是从未被赋值的自然状态。

3. 注意事项

3.1 全局 undefined 属性

值得一提的是,全局 undefined 属性就表示 undefined 值,也就是说 undefined 是全局范围的一个变量。如下:

typeof undefined === 'undefined';         // true
typeof window.undefined === 'undefined';  // true
console.log(undefined);         // undefined
console.log(window.undefined);  // undefined

它和自动赋的 undefined 值是相等的。如下:

let foo, bar;
undefined === undefined;   // true
foo === bar;               // true
foo === undefined;         // true
foo === window.undefined;  // true

3.2 undefined 不是关键字

这是 JavaScript 语言公认的设计失误之一。

根据 ES5 规范,现代浏览器里的 undefined 变量是不可配置、不可写的属性,所以在全局作用域里给它赋值是不会生效的(虽然情况并非总是如此,但应该避免覆盖它的值)。

window.undefined = 'hello';
console.log(window.undefined);  // undefined

但是,由于 undefined 不是关键字,这就能让我们在非全局作用域里定义一个名为 undefined 的变量,且能给它随便赋值。如下:

(function() {
  var undefined = 'hello'; // 但是,应避免这样做
  console.log(undefined, typeof undefined);  // hello string
})();

// 但是,应避免这样做
(function(undefined) {
  console.log(undefined, typeof undefined);  // world string
})('world');

3.3 判断值是否是 undefined

正是考虑到全局作用域里的 undefined 变量的值有被修改的风险,且在非全局作用域里 undefined 可能就是一个普通的变量,所以在实际开发中,如果要判断一个变量的值是否是 undefined 值,一般不直接使用 undefined 变量。 常见的替代方法有两个。

方法一:用 typeof 判断其类型值。而且当变量没有被声明时,也不会报错。

if (typeof foo === 'undefined') {
}

方法二:用 void 0 来替代 undefined 变量。void 运算符计算给定的表达值(是一个或多个常量/变量/函数和运算符的组合),然后返回 undefined 值。

if (foo === void 0) {
} // 如果变量未声明,会报错 ReferenceError: foo is not defined

4. 总结

这部分介绍了 Undefined 类型和它对应的 undefined 值,需要注意的是,在 JavaScript 中,undefined 不是关键字而是 window 上的一个属性。

考虑到 window.undefined 的值可能被覆盖,所以当要判断一个变量的值是不是 undefined 的时候,一般不直接使用 undefined 变量,而是用 typeof 或者 void 0 来替代。

5. 主要参考

Last updated