前段时间在群里面摸鱼的时候,有一个大佬说起了他参加的一个面试的面试题,聊一聊undefined和null。当时我带入了一下面试的场景,发现如果这个题问我的话我大概会说undefined和null转成布尔值都是false,undefined==null,typeof null == 'object',null转为数值是0,undefined转为数值是NaN,大体上我也就只能说出这些了。
但是大佬表示关于这个,他和面试官做了深切持久的交流。要么说大佬就是大佬,在这种平时我注意不到的地方人家能说出东西。我痛定思痛,决定研究一下这两个,然后发现不研究不知道,研究了还是不知道。所以决定水一篇文章,抛砖引玉一下,希望有大佬可以在我的说法上补充一下,给我一个学习的机会。
undefined
为什么先说undefined呢,随意说的,反正总有一个要先说嘛。
undefined,一个特殊值,通常用于指示变量尚未赋值。在高级程序设计语言设计应用程序时,用于指示变量尚未用单等号进行赋值。当然,这是百度百科的解释,不过大体上也概括了undefined的大致定位。所以获取一个undefined的方法大体上是四种。
1: 声明变量后不赋值
这里面a,b,c都是声明变量之后未赋值的状态,a和b都是直接声明,c是函数调用时未传入参数,导致参数未赋值。我把这两种情况就列为一种了。
2: 访问对象上不存在的属性
3: void对值进行运算
这个情况在日常业务逻辑的开发中其实遇到的并不多,我上次使用还是使用void让后面的函数可以省去括号的方式调用。
当然,如果不用void,用其他的一元运算符也是可以执行的。
说回void,其实void后面无论是跟字符串,还是跟任意数值,或者是任何的数据类型,最终返回都是undefined,但是目前约定俗成的还是void 0的方式返回undefined。
4:调用一个没有返回值的函数
目前我知道的值为undefined的操作就这四个了。
那说回void,为什么要设计这么一个东西来返回undefined呢,主要是因为undefined这个东西他不是一个保留字。
这里我们先说一下保留字,保留字是指高级函数中已经定义过的字,程序员不能再将这些字作为变量名、过程名或函数名使用。js的保留字还是挺多的,像是上文中使用过的let、function、void就都是保留字,但是这里面不存在undefined,这就会导致undefined如果直接使用的话容易出现一点小问题。
当然,这个问题浏览器有考虑过,所以我们如果直接对undefined进行赋值的话是无法修改的。
因为这个属性是无法修改,无法枚举,无法设置的。但是如果是另一个作用域的情况就不好说了。
undefined需要存在,但是有这样的问题,所以就需要我们之前说到的void来对需要赋值为undefined的变量进行赋值了。说的有点绕,反正是这么个意思。至于为什么需要undefined呢,建议阅读# 我们为什么需要 undefined?。
null
说完undefined我们再说说null。null表示的是这个变量我声明了,而且赋值了,但是我赋的是空值。日常我能接触到null的地方只有两个个,一个是原型链的尽头是null,另一个就是当一个变量我不需要了,就可以通过赋值null的方法,让变量之前的值被回收。
null和undefined最大的区别就是null是一个保留字,是无法赋值的。至于typeof null是object的情况,不同人有不同的理解。有的人认为这是null的值全是0,导致的typeof的bug,也有人认为null也是一个对象,只不过是一个空的对象。反正每个人有每个人的理解,我是理解不上去的,能力有限。
关于null,我是真不知道能说点什么,null本身表示空,所以我们也尽量少去描述这个空吧。