undefined 的特殊行为

使用 var 声明但没有进行初始化定义的变量,其值默认为 undefined

var aa; 
console.log(aa);  // undeifned

直接使用未声明的变量(console.log(aa))会报错:


但对未声明的变量使用 typeof 却不会报错。

console.log(typeof a)   // undefined

比较 nullundefined

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

对于 undefinednull 的相等性测试,返回 true。这是因为,undefined 是由 null 派生而来的。但是,这两者差别很大,之所以要设置两个值,让我们从历史原因说起吧

1)历史原因:
1995 年 JavaScript 诞生时,最初像 Java 一样只设置了 null 作为表示"无"的值。根据 C 语言的传统, null 被设计成可以自动转为0。但是,JavaScript 的设计者 Brendan Eich 觉得这样做还不够,有两个原因。首先,null 像在 Java 里一样,被当成一个对象。但是,JavaScript 的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich 觉得表示"无"的值最好不是对象;其次,JavaScript 的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich 觉得,如果 null 自动转为 0,很不容易发现错误。
因此,Brendan Eich 又额外设计了一个 undefined

2)最初设计:
JavaScript 的最初版本是这样区分的:null 是一个表示"无"的对象,转为数值时为 0;undefined 是一个表示"无"的原始值,转为数值时为 NaN。

Number(undefined)
// NaN
5 + undefined
// NaN

3)目前的用法:
但是,上面这样的区分,在实践中很快就被证明不可行。实践中有很多需要注意的地方。

null

null 是基本数据类型之一,值仅有一个,即为 null。它表示"空对象"(因此类型检测返回对象),即如果有对象,就会是一个具体的对象,如果没对象,就是 null。典型用法是:
(1)作为函数的参数,表示该函数的参数不是对象。
(2)作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype) // null    
typeof null     // object

如果定义的变量准备在将来用来保存对象,那么最好将该变量初始化为 null 而不是其他值。这样做不仅可以体现 null 作为空对象指针的惯例,而且也有助于进一步区分 nullundefined
只要直接检查 null 值就可以知道相应的变量是否已经保存了一个对象的引用,如下面的例子:

if(abc != null){
//对abc执行某些操作
}

undefined

undefined 是基本数据类型之一,值仅有一个,即为 undefined。它表示"缺少值"(因此类型检测返回 undefined),即此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于 undefined
(2) 调用函数时,应该提供的参数没有提供,该参数等于 undefined
(3)对象没有赋值的属性,该属性的值为 undefined
(4)函数没有返回值时,默认返回 undefined

var i;
i // undefined
function f(x){
    console.log(x)
}
f() // undefined
var o = new Object();
o.p // undefined
var x = f();
var exp = undefined;
console.log(x) // undefined

undefinednull 的检测

如何检测某个变量是 undefined

错误的用法:

if(abc == undefined)        
// 正如上面所说,js规定用`==` 判断时,null和undefined是等同的

正确的用法:

if (typeof(abc) == "undefined")   
// 或者最简单的办法:
if(abc === undefined)

PS:注意 typeof 的用法有运算符形式和函数形式,即 if(typeof(abc) == "undefined")if(typeof abc == "undefined") 效果是一样的。另外,由于 typeof 会返回诸如 "number" 的字符串形式的结果,因此右操作数应注意加双引号表示字符串。

如何检测某个变量是 null

错误的用法:

if(abc == null)      
// 解释同上。不过:要判断abc是 null 或者 undefined 时可使用这个方法。
if (!abc)        
// 这个的原理是:abc为假值,则 ! abc为真值,条件成立。然而,假值也可能是undefined,0 或 false。不过:要判断 abc是null、undefined、0 或者false 时可使用本法。 
if(typeof abc == "null")
//  为了向下兼容,abc 为 null 时,typeof null 总返回 object,所以不能这样判断。
if (isNull(abc))
//   VBScript 中有 IsNull 这个函数,但 JavaScript 中没有。

正确的用法:

if (! abc && typeof abc != "undefined" && abc != 0)
// 这个的原理是:如果!abc 成立,则 abc 为假值,则 abc 要么是undefined,0,false或者null 。typeof abc!= "undefined" 排除了 undefined;exp != 0 排除了0 和 false (0= =false,0= =0)。所以,abc一定是剩下的null。

// 或者使用最简单的方法:   
if (abc === null)