JavaScript中 null 和 undefined 的区别

3,156 阅读3分钟

undefined 和 null 是 Javascript 中两种特殊的原始数据类型(Primary Type),它们都只有一个值,分别对应 undefined 和 null,这两种不同类型的值,即有着不同的语义和场景,但又表现出较为相似的行为。

一、JS 中的 null

1. 描述:

① 是 JavaScript 基本类型之一,特指对象的值未设置,是表示缺少的标识,指示变量未指向任何对象,把 null 看为尚未创建的对象,也许更好理解;
② 是一个字面量,不像 undefined,它不是全局对象的一个属性;
③ 在布尔运算中被认为是 false;
④ 与其他任何对象一样永远不会被 JavaScript 隐式赋值给变量。

注:如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为 false,其他值都视为 true。

undefined
null
false
0
NaN
"" 或 ''(空字符串)

2. 典型用法:

(1) 作为函数的参数,表示该函数的参数为空。

(2) 作为对象原型链的终点。

二、JS 中的 undefined

  1. 描述:
    ① 是 JavaScript 基本类型之一,表示 “缺少值”,就是此处应该有一个值,但是还没有定义;
    ② 是 JavaScript 在运行时创建的全局变量,是全局对象的一个属性;
    ③ 在布尔运算中被认为是 false。
    注:有关全局对象和全局变量,可参考 javascript 全局对象与全局变量

  2. 典型用法:

    (1)变量被声明但没有赋值时,就等于 undefined。

    (2)对象的某个属性没有赋值时,该属性的值为 undefined。

    (3)调用函数过程中,应该提供的参数没有提供时,该参数就等于 undefined。

    (4)函数没有返回值时,默认返回 undefined。

三、JS 中的 undefined 和 null 的区别有:

1. 相等但不全等:

	null == undefined	// true
	null === undefined 	// false

实际上,undefined 值是派生自 null 值的,ECMAScript 标准规定对二者进行相等性测试要返回 true,可以理解为 null 和 undefined 都代表着无效的值,所以二者相等,但由于是两种不同的原始数据类型,所以不全等。

注:

	typeof undefined	// undefined
	typeof null		// object

① typeof null 结果是 object,这是个历史遗留 bug,参考 js 中 typeof 用法详细介绍;
② 在 ECMA6 中,曾经有提案为历史平反,将 typeof null 的值纠正为 null,但最后提案被拒了,理由是历史遗留代码太多,不想得罪人,不如继续将错就错当和事老。

2. 在数字运算中被转换为 number 类型的值不同

在 null 上执行算术转换时,确定的值为 0

	let a = 10 + null;
	
	console.log(a);	// 10	

undefined 得出的结果为 NaN

	let b = 10 + undefined;
	
	console.log(b);	// NaN

注:有关加法运算中的隐式类型转换,可参考 “加号 +” 的运算原理(详细!!!)

相同点:

都是原始类型的值,保存在栈中变量本地

何时使用:

null当使用完一个比较大的对象时,需要对其进行释放内存时,设置为null;

var arr=["aa","bb","cc"];
arr=null;//释放指向数组的引用

额外补充的知识

数组进行相等比较是一个怪物,看下面的例子:

	[] == ''   // -> true
	[] == 0    // -> true
	[''] == '' // -> true
	[0] == 0   // -> true
	[0] == ''  // -> false
	[''] == 0  // -> true
	
	[null] == ''      // true
	[null] == 0       // true
	[undefined] == '' // true
	[undefined] == 0  // true
	
	[[]] == 0  // true
	[[]] == '' // true
	
	[[[[[[]]]]]] == '' // true
	[[[[[[]]]]]] == 0  // true
	
	[[[[[[ null ]]]]]] == 0  // true
	[[[[[[ null ]]]]]] == '' // true
	
	[[[[[[ undefined ]]]]]] == 0  // true
	[[[[[[ undefined ]]]]]] == '' // true

个人理解:
以上例子可以理解为,在比较过程中, [] 、[null] 和 [undefined] 都隐式转换为 '';
对于最里层的 [] ,不管外层嵌套多少个 [] ,最终都可看成只有最里层一个 [] 。