Fork me on GitHub

undefined null 区别

大多数计算机语言,有且仅有一个表示”无”的值,比如,C 语言的 NULL ,Java 语言的 null ,Python 语言的 None,Ruby 语言的 nil 。

但是,JavaScript 语言居然有两个表示”无”的值:undefined 和 null 。

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

1. 不同

  • null

null 的字面意思是:空值 。这个值的语义是,希望表示, 一个对象被人为的重置为空对象,而非一个变量最原始的状态。在内存里的表示就是,栈中的变量没有指向堆中的内存对象,即:

img

当一个对象被赋值了null 以后,原来的对象在内存中就处于游离状态,GC 会择机回收该对象并释放内存。因此,如果需要释放某个对象,就将变量设置为 null,即表示该对象已经被清空,目前无效状态

与 null 相关的另外一个问题需要解释一下:

1
typeof null == 'object'

null 有属于自己的类型 Null,而不属于Object类型,typeof 之所以会判定为 Object 类型,是因为JavaScript 数据类型在底层都是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,而 null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object 类型。

1
2
3
4
5
- 000 - 对象,数据是对象的应用
- 1 - 整型,数据是31位带符号整数
- 010 - 双精度类型,数据是双精度数字
- 100 - 字符串,数据是字符串
- 110 - 布尔类型,数据是布尔值

其实,我们可以通过另一种方法获取 null 的真实类型

1
Object.prototype.toString.call(null) ; // [object Null]

通过 Object 原型上的toString() 方法可以获取到 JavaScript 中对象的真实数据类型,当然 undefined 类型也可以通过这种方式来获取:

1
Object.prototype.toString.call(undefined) ; // [object Undefined]
  • undefined

undefined 的字面意思就是:未定义的值 。这个值的语义是,希望表示一个变量最原始的状态,而非人为操作的结果。这种原始状态会在以下 5 种场景中出现:

1
2
3
4
5
- 变量被声明了,但没有赋值时,就等于undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于undefined。
- 对象没有赋值的属性,该属性的值为undefined。
- 函数没有返回值时,默认返回undefined。
- 使用 void 对表达式求值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var i;
i // undefined

function f(x){console.log(x)}
f() // undefined

var o = new Object();
o.p // undefined

var x = f();
x // undefined

// ECMAScript 明确规定 void 操作符 对任何表达式求值都返回 undefined
void 0 ; // undefined
void false; // undefined
void []; // undefined
void null; // undefined
void function fn(){} ; // undefined

2. 相似性

虽然 undefined 和 null 的语义和场景不同,但总而言之,它们都表示的是一个无效的值。 因此,在 JavaScript 中对这类值访问属性时,都会得到异常的结果:

1
2
null.toString(); // Cannot read property 'toString' of null
undefined.toString(); // Cannot read property 'toString' of undefined

ECMAScript 规范认为,既然 null 和 undefined 的行为很相似,并且都表示 一个无效的值,那么它们所表示的内容也具有相似性,即有

1
undefined == null; // true

不要试图通过转换数据类型来解释这个结论,因为:

1
2
3
4
5
Number(null); // 0
Number(undefined); // NaN

// 在比较相等性之前,null 没有被转换为其他类型
null == 0 ; //false

但 === 会返回 false ,因为全等操作 === 在比较相等性的时候,不会主动转换分项的数据类型,而两者又不属于同一种类型:

1
2
undefined === null; // false,类型不相同
undefined !== null; // true, 类型不相同

总结:

用一句话总结两者的区别就是:undefined 表示一个变量自然的、最原始的状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。所以,在实际使用过程中,为了保证变量所代表的语义,不要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。

参考链接:

-------------本文结束感谢您的阅读-------------