我的编程空间,编程开发者的网络收藏夹
学习永远不晚

一文让你彻底弄懂js中undefined和null的区别

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

一文让你彻底弄懂js中undefined和null的区别

前言

undefined 和 null 的区别是个老生常谈的话题了,之前我对二者的区别只是简单理解,例如二者转成 Boolean 类型都是 false、使用 == 进行比较时为 true、使用 === 进行比较时为 false 等,却没有真正系统地总结二者的区别。

某天,下班前几分钟,我彻底弄懂了 undefined 和 null 的区别。

一、基本概念

1、undefined

undefined 是“全局对象”的一个属性。也就是说,它是全局作用域的一个变量(下面展开对 undefined 变量的赋值操作)。undefined 的最初值就是原始数据类型 undefined。

2、null

null 是一个字面量,不像 undefined,它不是“全局对象”的一个属性。null 是表示缺少的标识,指示变量未指向任何对象。把 null 作为尚未创建的对象,或许更好理解。在 API 中,null 常使用来表示返回类型应是一个对象,但没有关联某个具体对象的这么一个值。

二、简单区别

总的来说,null 和 undefined 都表示空,主要区别在于 undefined 表示尚未初始化的变量的值,而 null 表示该变量有意缺少对象指向。

undefined

  • 这个变量从根本上就没有定义。
  • 隐藏式 空值。

null

  • 这个值虽然定义了,但它并未指向任何内存中的对象。
  • 声明式 空值。

以下是一张经典的图片,帮助我们理解。

三、表现形式

undefined 和 null 在 JavaScript 中有什么不同的表现形式,理解这些表现形式,可以帮助我们更好地理解 undefined 和 null 的区别。

1、typeof

console.log(typeof undefined);   // 'undefined'
console.log(typeof null);   // 'object'

typeof null 为 object 是一个历史遗留问题,直到现阶段都无法被修复。

在 JavaScript 初始版本中,值以 32位 存储。前 3位 表示数据类型的标记,其余位则表示值。

对于所有对象类型,它的前 3位 都以 000 作为类型标记位。在 JavaScript 早期版本中,null 被认为是一个特殊的值,用来对应 C 中的空指针,但 JavaScript 中没有 C 中的指针概念,所以 null 意味着什么都没有或者 void 并以 全0(32位)表示。

因此每当 JavaScript 读取 null 时,它的前 3位 将它视为对象类型,这也是为什么 typeof null 返回 object 的原因。

2、== 与 ===

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

这一点相信大家都明白,== 比较的是值,而 === 比较的是值跟类型。undefined 和 null 的布尔值都为 false,因此在用 == 比较时,为 true;而 undefined 和 null 的类型不同,因此在用 === 比较时为 false。

3、Object.prototype.toString.call

console.log( Object.prototype.toString.call(undefined) );   // '[object Undefined]'
console.log( Object.prototype.toString.call(null) );   // '[object Null]'

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]]。这是一个内部属性,其格式为 [object Xxx],其中 Xxx 就是对象的类型。

那么既然在 JavaScript 中,万物皆对象,为什么 xxx.toString() 不能返回变量类型?

这是因为各个类中重写了 toString(),因此需要调用 Object 中的 toString(),且必须使用 toString.call() 的方式调用。对于 Object 对象,直接调用 toString() 就能返回 [object Object];而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

4、+ 运算 与 Number()

let a = undefined + 1;
let b = null + 1;
console.log(a);   // NaN
console.log(b);   // 1
 
console.log(Number(undefined));   // NaN
console.log(Number(null));   // 0

这涉及到 JavaScript 中的隐式类型转换,在执行加法运算前,隐式类型转换会尝试将表达式中的变量转换为 number 类型。如:'1' + 1 会得到结果 11。

null 转化为 number 时,会转换成 0。

undefined 转换为 number 时,会转换为 NaN。

5、JSON.stringify

console.log( JSON.stringify({a: undefined}) );   // '{}'
console.log( JSON.stringify({b: null}) );   // '{b: null}'
console.log( JSON.stringify({a: undefined, b: null}) );   // '{b: null}'

JSON 会将 undefined 对应的 key 删除,这是因为 JSON 自身的转换原则。在 undefined 的情况下,有无该条数据是没有区别的,因为他们在表现形式上并无不同。

let obj1 = { a: undefined };
let obj2 = {};
 
console.log(obj1.a);   // undefined
console.log(obj2.a);   // undefined

6、let undefiend = 'test'

function test(params) {
    let undefined = 'test';   // 该作用域内undefined为一个变量,赋值为test
    return params === undefined;
}
 
test();   // false
test(undefined);   // false
test('test');   // ture
 
let undefined = 'test';   // Uncaught SyntaxError: Identifier 'undefined' has already been declared

JavaScript 对于 undefined 的限制方式为全局创建了一个只读的 undefined,但是并没有彻底禁止局部 undefined 变量的定义。

请在任何时候,都不要对 undefined 变量进行覆盖,就算是你的 JSON 转换将 undefined 转换为 '' ,也不要通过该操作进行,这将是及其危险的行为。

四、建议

如果你需要使用 undefined 定义空值,请不要采取以下两种方式:

  • let a;
  • let a = undefined;

进而采取下面这种方式显式声明 undefined:

  • let a = void 0;

附:null在类型判断时为什么是object

这是一段历史,1995年Javascript诞生之初, 在实现js类型判断的方法时(也就是typeof),数值是以32位存储的,由标志位(1~3位)和数值组成。标志位存储的是低位的数据。这里有五种标志位:

  • 000 表示对象
  • 1 表示整数
  • 010 表示浮点数
  • 100 表示字符串
  • 110 表示布尔类型

有两个特殊值:

  • undefined用-2^30表示
  • null用全0表示

这不巧了吗这不是,null的低位也是000,所以误打误撞成为了object,这一点一直被认为是个bug,直到es6的时候typeof null === 'null'的提案被否决,typeof null === 'object'变成了feature,也就是说这个"bug"不会被“修复”了

总结

到此这篇关于undefined和null区别的文章就介绍到这了,更多相关undefined和null的区别内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

一文让你彻底弄懂js中undefined和null的区别

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

一文讲解TypeScript中的null和undefined的区别

本文深入介绍了TypeScript中null和undefined的区别。尽管它们在某些情况下可以互相替代,但它们在语义和用法上存在着重要的差异。

一文搞定双链表,让你彻底弄懂线性表的链式实现

单链表和双链表都是线性表的链式实现,它们的主要区别在于节点结构。单链表的节点包含数据字段 Data 和一个指向下一个节点的指针 Next,而双链表的节点除了 Data 和 Next,还包含指向前一个节点的指针 Pre。这个区别会导致它们在操

一文带你搞懂JS中导入模块import和require的区别

JavaScript中,模块是一种可重用的代码块,它将一些代码打包成一个单独的单元,并且可以在其他代码中进行导入和使用。JavaScript中有两种常用的方式:使用import和require,本文主要聊聊他们二者的区别
2023-03-02

编程热搜

目录