当前位置:首页 > 杂谈 > 正文内容

深入探究:null 和 undefined 究竟有何区别?(null和undefined的区别历史)

2023-08-02 19:44:57TONY杂谈84

简单区分

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

undefined这个变量从根本上就没有定义隐藏式 空值null这个值虽然定义了,但它并未指向任何内存中的对象声明式 空值

MDN 中给出的定义

null

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

undefined

undefined 是 全局对象 的一个属性。也就是说,它是全局作用域的一个变量。undefined 的最初值就是原始数据类型 undefined 。

一张神奇的图片

接下来我们看一张比较经典的图片,该图来自 stackoverflow 的回答,本人没有找到准确的出处。

表现形式

在更深入理解 null 和 undefined 的区别前,我们首先要知道 null 和 undefined 在 JS 中有什么不同的表现形式,用以方便我们更好的理解 null 和 undefined 的区别。

typeof

typeof null // object typeof undefined // undefined 复制代码

Object.prototype.toString.call

typeof null // [object Null] typeof undefined // [object Undefined] 复制代码

== 与 ===

null == undefined // true null === undefined // false !!null === !!undefined // true 复制代码

Object.getPrototypeOf(Object.prototype)

JavaScript 中第一个对象的原型指向 null 。

Object.getPrototypeOf(Object.prototype) // null 复制代码

+ 运算 与 Number()

let a = undefined + 1 // NaN let b = null + 1 // 1 Number(undefined) // NaN Number(null) // 0 复制代码

JSON

JSON.stringify({a: undefined}) // {} JSON.stringify({b: null}) // {b: null} JSON.stringify({a: undefined, b: null}) // {b: null} 复制代码

let undefiend = test

function test(n) { let undefined = test return n === undefined } test() // false test(undefined) // false test(test) // ture let undefined = test // Uncaught SyntaxError: Identifier undefined has already been declared 复制代码

深入探索

为什么 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 的原因。

为什么 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 来调用才能返回正确的类型信息。

为什么 == 和 === 对比会出现 true 和 false ?

很多文章说:undefined 的布尔值是 false , null 的布尔值也是 false ,所以它们在比较时都转化为了 false ,所以 undefined == null 。

实际上并不是这样的。

ECMA 在 11.9.3 章节中明确告诉我们:If x is null and y is undefined, return true.If x is undefined and y is null, return true.

这是 JavaScript 底层的内容了,至于更深入的内容,如果有兴趣可以扒一扒 JavaScript 的源码。

为什么 null + 1 和 undefined + 1 表现不同?

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

null 转化为 number 时,会转换成 0undefined 转换为 number 时,会转换为 NaN

至于为什么执行如此的转换方式,我猜测是 JavaScript 早期的一个糟糕设计。

从语言学的角度来看:

null 意味着一个明确的没有指向的空值,而 undefined 则意味着一个未知的值。

在某种程度上, 0 意味着数字空值。

这虽然看起来有些牵强,但是我在这一阶段能所最能想到的可能了。

为什么 JSON.stringify 会将值为 undefined 的内容删除?

其实这条没有很好的解释方式, JSON 会将 undefined 对应的 key 删除,这是 JSON 自身的转换原则。

在 undefined 的情况下,有无该条数据是没有区别的,因为他们在表现形式上并无不同:

let obj1 = { a: undefined } let obj2 = {} console.log(obj1.a) // undefined console.log(obj2.a) // undefined 复制代码

但需要注意的是,你可能在调用接口时,需要对 JSON 格式的数据中的 undefied 进行特殊处理。

为什么 let undefiend = test 可以覆盖掉 JavaScript 自身的 undefined?

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

据说在 JavaScript 高版本禁止了该操作,但我没有准确的依据。

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

总结

关于使用 undefined 还是 null

这是一条公说公有理婆说婆有理的争议内容。

本人更倾向于使用 null ,因为这是显示定义空值的方式。我并不能给出准确的理由。

但关于使用 undefined 我有一条建议:

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

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

let a = void 0;

转载自:https://juejin.cn/post/7051144396615450655

“深入探究:null 和 undefined 究竟有何区别?(null和undefined的区别历史)” 的相关文章

提示!2022年一级建造师考试补考准考证打印入口已开通

提示!2022年一级建造师考试补考准考证打印入口已开通

原标题:提示!2022年一级建造师考试补考准考证打印入口已开通 2022年一级建造师补考准考证打印时间为3月17日起,打印官网为中国人事考试网。各地准考证打印持续时间不同,具体打印时间以各地补考公告中公布的时间为准(2022年各省一建补考准考证打印时间)。 2022年一级...

抖店应用云服务平台「抖店云」上线 开启服务商招募

抖店应用云服务平台「抖店云」上线 开启服务商招募

站长之家(ChinaZ.com)7月5日 消息:日前,抖音电商联合火山引擎推出电商应用云服务平台抖店云(网址:https://opencloud.jinritemai.com/home),并正式开启服务商招募。 据介绍,抖音云通过云端数据容器,打造弹性的云计算资源、可靠的安全服务、...

国内商品住宅价格环比上涨城市继续增加,70个城市中55个上涨

国内商品住宅价格环比上涨城市继续增加,70个城市中55个上涨

国家统计局3月16日发布了最新一期70个大中城市商品住宅销售价格变动情况。数据显示,2月份随着政策效果逐步显现及住房需求进一步释放,国内各线城市商品住宅销售价格环比总体上涨,一线城市商品住宅销售价格同比上涨、二三线城市同比降幅收窄。 国家统计局城市司首席统计师绳国庆表示,...

2月70城房价|一线城市上涨幅度明显,南充新房价格持续下跌!

2月70城房价|一线城市上涨幅度明显,南充新房价格持续下跌!

3月16日,全国70个大中城市2月份新建和二手房住宅销售价格变动数据出炉。根据统计,2月份环比波动不明显,详情如下: 通过上表数据可知,今年2月份新房销售价格环比上涨的城市有27个,比上月减少一个,上...

工行重庆自贸区分行:同心战“疫”守好金融服务保障线

工行重庆自贸区分行:同心战“疫”守好金融服务保障线

重庆本轮疫情发生以来,工行重庆自贸区分行党员、员工主动请缨,迎难而上,用实际行动筑牢金融抗疫防线。疫情期间,工行重庆自贸区分行即将退休的老党员廖霞主动请缨负责后勤保障工作,及时维护网点对外营业时间,确保对外公示与实际保持一致;及时处理印章流程,确保重点岗位人员通行证顺利办理。受疫情影响,许多客户只能...

剑网三近期外观盒子调整,策划亲自上阵,求生欲强主要为带货

剑网三近期外观盒子调整,策划亲自上阵,求生欲强主要为带货

每到节假日剑网三都会推出大大小小的活动庆祝一番,那么,就快到了一年一度的中秋节了,官方在这几天则爆料了许多新外观,中秋盒子,二胡盒子和复刻外观等,神奇的是,官博在放出新外观盒子的消息之后居然没有对新外观多做解释,而是对新外观的布料和细节进行讲解,这是何意? 其实是这次中秋...