关于 JavaScript 的 null 和 undefined,判断 null 的真实类型

null、undefined

undefined:表示一个变量最原始的状态,而非人为操作的结果 null:表示一个对象被人为的重置为空对象,而非一个变量最原始的状态

《JavaScript高级程序设计》一书 53 页:

由于相等和不相等操作符存在类型转换问题,而为了保持代码中数据类型的完整性,我们推荐使用全等和不全等操作符

记住:

null == undefined 会返回 true; null === undefined 会返回 false;

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

1. undefined

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

【1】声明了一个变量,但没有赋值

1 var foo;
2 console.log(foo); //undefined

访问foo,返回了undefined,表示这个变量自从声明了以后,就从来没有使用过,也没有定义过任何有效的值,即处于一种原始而不可用的状态

【2】访问对象上不存在的属性

1 console.log(Object.foo); // undefined

访问Object对象上的 foo 属性,同样也返回 undefined , 表示Object 上不存在或者没有定义名为 “foo” 的属性

【3】函数定义了形参,但没有传递实参

1 //函数定义了形参 a
2 function fn(a) {
3     console.log(a); //undefined
4 }
5 fn(); //未传递实参

函数 fn 定义了形参a, 但 fn 被调用时没有传递参数,因此,fn 运行时的参数 a 就是一个原始的、未被赋值的变量

【4】使用 void 对表达式求值

1 void 0 ; // undefined
2 void false; //undefined
3 void []; //undefined
4 void null; //undefined
5 void function fn(){} ; //undefined

ECMAScript 规范 void 操作符 对任何表达式求值都返回 undefined ,这个和函数执行操作后没有返回值的作用是一样的,JavaScript中的函数都有返回值,当没有 return 操作时,就默认返回一个原始的状态值,这个值就是undefined,表明函数的返回值未被定义。

因此,undefined 一般都来自于某个表达式最原始的状态值,不是人为操作的结果。当然,你也可以手动给一个变量赋值 undefined,但这样做没有意义,因为一个变量不赋值就是 undefined

2. null

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

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

3. 判断 null、undefined 数据类型

获取 null 的真实类型:

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

通过 Object 原型上的 toString() 方法可以获取到JavaScript 中对象的真实数据类型

当然 undefined 类型也可以通过这种方式来获取:

1 // 要知道,使用 typeof 就可以鉴别 undefined 类型了
2 // typeof undefined === 'undefined'
3 Object.prototype.toString.call(undefined); // [object Undefined]

除此以外,还有比如 Array 的情况,因为 typeof Array 也会返回 object,检测是否是 Array 的方法:

1 // 以下三种方法,如果是数组,返回 true
2 arr instanceof Array;
3 Array.isArray(arr); // ES5方法
4 Object.prototype.toString.call(arr); // [object Array]

4. 相似性

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

1 Cannot read property 'foo' of null
2 Cannot read property 'foo' of undefined

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

1 null == undefined; // true

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

1 Number(null); // 0
2 Number(undefined); // NaN,注意 NaN 不等于任何
3 
4 // 在比较相等性之前,null 没有被转换为其他类型
5 null == 0 ; // false

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

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

总结

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

相关链接

原文地址:https://github.com/Krryxa/WORK-LEARNING/issues/37

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏codingforever

经典算法巡礼(一) -- 排序之冒泡排序

事实上,她重复地遍历需要排序的元素,一次比较相邻的两个元素,如果不满足预先定义的比较条件,则交换;否则继续下一组元素比较,直至遍历完成需要排序的所有元素。当然,...

4320
来自专栏转载gongluck的CSDN博客

c语言中函数参数处理顺序-从右向左

c语言中函数参数处理顺序-从右向左      下面我们来看2个案例,分析下c语言中函数参数处理顺序。      第一个: #include "stdio....

44960
来自专栏Java帮帮-微信公众号-技术文章全总结

第十三天 面向对象-final static 匿名对象内部类包代码块【悟空教程】

15240
来自专栏一枝花算不算浪漫

[C#基础]基础知识一: 面向对象的基本知识.

437170
来自专栏Bingo的深度学习杂货店

Q189 Rotate Array

Rotate an array of n elements to the right by k steps. For example, with n = 7 a...

37770
来自专栏Python小屋

1000道Python题库系列分享四(40道)

热烈庆祝2018年2月董付国老师《Python程序设计(第2版)》出版18个月第5次印刷,《Python可以这样学》出版12个月第5次印刷,系列教材《Pytho...

1K70
来自专栏猿人谷

【Objective-C】05-第一个OC的类

说明:这个Objective-C专题,是学习iOS开发的前奏,也为了让有面向对象语言开发经验的程序员,能够快速上手Objective-C。如果你还没有编程经验,...

224100
来自专栏Bug生活2048

Python自学之路-内置函数说明及实例(二)

这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

14910
来自专栏日常学python

深入理解python中的类和对象

刚开始学习python的时候或者其他的是面向对象的编程语言的时候,难免会对类和对象理解得不太清楚。所以今天和大家分享下python中的类和对象,深入理解下pyt...

11200
来自专栏C/C++基础

多字节与宽字符串的相互转换

说到多字节字符串与宽字符串,不得不说一下多字节字符与宽字符。多字节字符实际上是由多个字节来表示一个字符,在各个国家和地区采用不同的编码方案,不同编码方案字符码值...

17420

扫码关注云+社区

领取腾讯云代金券