JS中的null和undefined,undefined为啥用void 0代替?

栏目: JavaScript · 发布时间: 5年前

内容简介:某天,在看某位同学的js代码,代码中发现了一个奇怪的东西undefined和null是js中类型七种数据类型,这两种数据的区别是null是有一些奇怪的地方,例如常见的面试题

  某天,在看某位同学的js代码,代码中发现了一个奇怪的东西 void 0 ,虽然第一眼看不懂这是什么东西,但是根据上下文,这里应该是想判断是否等于undefined,为什么要这样写的,有什么渊源吗?顺便就把undefined和null都拿出来复习了一下.

介绍

  undefined和null是js中类型七种数据类型,这两种数据的区别是

  • undefined是声明了未定义
  • null是一个空指针,除非定义为null,否则不会出现null

null

   null是有一些奇怪的地方,例如常见的面试题

typeof null 为什么是object?

这道题目在我一开始学习js的时候就接触过,说是js设计的一个bug啦,只是因为旧代码太多,怕改正过来会造成影响,所以一直保持,也有的说这是一个空指针,空对象,所以为object.但是我总觉得这样说服力不够,于是我上网翻了一些资料

在 javascript 的最初版本中,使用的 32 位系统,并且底层都表示为2进制,为了性能考虑使用低位存储了变量的类型信息:

  • 000:对象

  • 1:整数

  • 010:浮点数

  • 100:字符串

  • 110:布尔

  • 全部为0: null

所以typeof就是利用这一机制去判断的,所以null全部为0就复合了对象的000,所以被判断为object

并且还有个注意点

null == undefined //true null和undefined用==比较结果是true,并且没有发生隐式转换,就是true
复制代码

undefined

  接下来就是undefined了,这个设计感觉也有个非常大的bug,那么重要的东西,竟然不是一个关键字,竟然是一个变量.一个变量意味着什么, 你可以随意更改它啊!!

  所以有的 程序员 就会利用void 0去代替undefined,鬼知道原来的undefined会不会被某个阴险小人替换了.

那么void 0到底是怎么来的?

根据ECMAScript,void后面接什么都是undefined,也有的说void 0 是从其他语言带过来的习惯,是一种老司机的写法,所以下次我们要用到undefined的时候就要void 0代替,这样比较显得老司机

undefined什么情况下会被替换?

这里我自己测试了一下

  • 在谷歌浏览器69.0.3497.100版本下
var undefined = 2;
    console.log(undefined); //undefined 
复制代码

结果是undefined,也就是在新版的谷歌浏览器里面的全局作用域下面是无法更改undefined的

const undefined = 2; //这次改用const
    console.log(undefined); //Identifier 'undefined' has already been declared
复制代码

用const则会报错,已经declared了,let也同样

  • 那就试试ie浏览器吧(IE11)
var undefined = 2;
    console.log(undefined); //undefined 
复制代码

这样的结果还是undefined,所以在ie11的全局作用域下面也不能替换

  • 直到ie8版本的浏览器发生了变化
var undefined = 2;
    console.log(undefined); //2
复制代码

竟然改变了,ie8的全局作用域下是可以改变undefined的

这样看来好像也没什么用是不是?ie8很多公司都不用去兼容了,慢着

  • 在谷歌浏览器69.0.3497.100版本下,我们试试在函数作用域下
(function () {
        var undefined = 2
        console.log(undefined);  //2 
    })()
复制代码

发现这样就改变了undefined

(function () {
        const undefined = 2
        console.log(undefined); //2
    })()
复制代码

const同样可行,并且在ie的11,10,9,8几个版本中,无一例外的,undefined都被覆盖了

为什么会这样呢?

  这时候想到,在全局作用域下,全局变量会变成window上面的一个属性,这时候我们查查看这个属性有什么特别不就知道原因了

console.log(Object.getOwnPropertyDescriptor(window, undefined)); //{value: undefined, writable: false, enumerable: false, configurable: false}
复制代码

这时候拿到数据属性可以看到,不可重写,不可枚举,不可改变特征值或者被删除,所以在全局作用域下面是不可以被重写的.

  那ie8呢?为什么可以?

console.log(Object.getOwnPropertyDescriptor(window, undefined)); //{configurable: false, enumerable: false, value: undefined, writable: true}
复制代码

ie8同样,不可枚举,不可删除或修改特征值,但是!!可以被重写!!所以ie8的全局作用域上面是可以被重写的!!

结论:虽然undefined在现在主流的绝大部分浏览器的全局作用域上面都是不能更改了,但是在函数作用域或者块级作用域下面还是能被重写的,当然绝大部分人应该都不会去干这种傻事,但是还是用viod 0吧,这样可以以防万一,同时也更像一个老司机的代码啊


以上所述就是小编给大家介绍的《JS中的null和undefined,undefined为啥用void 0代替?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms Unlocked

Algorithms Unlocked

Thomas H. Cormen / The MIT Press / 2013-3-1 / USD 25.00

Have you ever wondered how your GPS can find the fastest way to your destination, selecting one route from seemingly countless possibilities in mere seconds? How your credit card account number is pro......一起来看看 《Algorithms Unlocked》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具