javascript中的undefined

javascript 中的undefined有很多的迷惑性,非常让人难以理解。

undefined 等同于 “未声明” 吗?

undefined中文意思为“未定义”,我们可能就会认为undefined就是变量“未声明”。

但其实并不是这样,看下面的例子:

1
2
3
4
var a;

a; // undefined
b; // ReferenceError: b is not defined

我们只声明了变量a,但获取a时,返回的结果是undefined,获取b时抛出了一个异常。

这说明undefined不是“未声明”的意思,在引用“未声明”的变量时会抛出ReferenceError的异常。

安全守卫(safety guard)

上面的例子说明了“未声明”的变量在引用时会抛出异常。但是我们的代码有时需要依赖全局的某个变量,而且我们不知道该变量是否已被声明。我们可能会像下面那样写一个if语句来判断该变量是否存在。

1
2
3
if (DEBUG) {
console.log("Debugging is starting");
}

在上面例子中,如果DEBUG并未被声明的话,会抛出ReferenceError并打断了代码的运行。我们需要的是当DEBUG为 true 时,执行内部的逻辑,DEBUG为 falsy 或“未声明”时,跳过里面的代码,而不是抛出异常。

以下有多种方式实现一个安全守卫,防止 javascript 抛出异常。

方法 1:typeof
1
2
3
4
var a;

typeof a; // "undefined"
typeof b; // "undefined"

从上面的例子中可以发现,无论是已声明的还是未声明的变量,typeof 返回的结果都是undefined,而且typeof b也不会抛出异常。

可以利用这个特性,作为一个 safety guard。代码如下:

1
2
3
if (typeof DEBUG !== "undefined") {
console.log("Debugging is starting");
}
方法 2:对象属性
1
2
3
4
5
var person = {
name: "Allen"
};

person.gender; // undefined

上面的例子中可以得出,访问一个未定义的对象属性不会抛出异常。

我们知道,javascript 中全局的变量,其实就是window对象上的属性。结合上面得出的结论,我们可以利用该特性,实现 safety guard。

1
2
3
if (window.DEBUG) {
console.log("Debugging is starting");
}

但是,这个方法,不利与跨平台,应为在 nodejs 中没有window对象。