空值:Undifined类型、Null类型

一般来说,程序中表示空的只有 null。

JS 的设计者 Brendan Eich 却设计了一个 undefined,这无疑增加了程序复杂度。

1995年,JS 诞生时,最初像 Java 一样,只设置了 null 作为表示”无”的值。根据 C 语言的传统,null 被设计成可以自动转为 0。但是,JS 的设计者 Brendan Eich,觉得这样做还不够,有两个原因:

首先,null 像在 Java 里一样,被当成一个对象。

但是,JS 的值分成原始类型和对象类型两大类,Brendan Eich 觉得表示”无”的值最好不是对象。其次,JS 的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。

Brendan Eich 觉得,如果 null 自动转为 0,不易发现错误。因此,他又设计了一个 undefined。他是这样区分的:null 是一个表示”无”的对象,转为数值时为 0;undefined 是一个表示”无”的原始值,转为数值时为 NaN。

但是,目前 null 和 undefined 基本是同义的,都是原始类型,且只有一些细微的差别。


Undefined类型:undefined

# 当声明的变量未初始化时,该变量的默认值是undefined。所以,undefined通常表示变量没有初始化。

var test; // undefined
console.log(test == undefined); // true
var test = undefined;  // undefined
出现场景:已声明未赋值的变量 / 获取对象不存在的属性 / 无返回值的函数执行结果 / 函数参数没有传入 / void(expression)
 
var i;
console.log(i); // undefined
 
var o = {};
console.log(o.p); // undefined
 
function f(){};
console.log(f()); // undefined
 
function f(x){return x;}
console.log(f()); // undefined
 
console.log(void(0)); // undefined

# 对于尚未声明过的变量只能执行一项操作,使用typeof操作符检测其数据类型,严格模式下会出错。

typeof(test);  // undefined

# void(0)

//  由于undefined并不是一个关键字,其在IE8-浏览器中会被重写,在高版本函数作用域中也会被重写。
//  所以,可以用 void 0 来替换undefined。
 
var undefined = 10;
console.log(undefined);  // IE8-浏览器下为10,高版本浏览器下为undefined
 
function t(){
    var undefined = 10;
    console.log(undefined);
}
console.log(t());  // 所有浏览器下都是10

Null类型:null

Null类型只有一个值,即null。null是JavaScript的关键字,表示一个特殊值,常用来描述"空值"。

逻辑角度看,null值表示一个空对象指针;判断一个值是否为null类型的最佳方法是直接和null进行恒等比较。

console.log(document.getElementById('test'));  // null
 
// null是空对象指针,而[]是空数组,{}是空对象,三者不相同。
   console.log(typeof null);  // 'object

不同的对象在底层都表示为二进制,在JavaScript中二进制前三位都为0会被判断为object类型,null的二进制表示是全0,所以执行typeof时返回'object'。
尽管null和undefined是不同的,但它们都表示"值的空缺",null表示"空值",undefined表示"未定义"。两者往往可以互换。判断相等运算符==认为两者是相等的。

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

实际上,因为undefined和null不是构造器类型,所以它们没有任何的属性和方法,使用.和[]来存取
这两个值的成员或方法都会产生一个类型错误。