前言
对于JS的初学者,null和undefined这两个基本类型容易理不清关系,我刚开始学的时候也是这样的。智能社有关于这个问题的视频讲解,但为了方便初学者的理解,解释会不那么“正统”,不太能拿出去面试。所以把视频结合自己的理解一起来重新捋一捋。
null
null这个数据类型各个语言都有,意思也是差不多的。这个null一般JS不会主动给你,什么意思呢,就是需要你自己手动去赋值一个变量,才能有null这个值。
关键词:主动
在JS底层中,这个null其实是个0,例如:1+null = 1
,Number(null) = 0
。
这里涉及到了隐式转换规则强烈建议看:【JS基础】容易遗忘的数据类型转换,口诀都帮你整理了,收藏起来下次遇到直接击杀
但为啥typeof null === 'object'
呢?
这个typeof
不是一个函数,是作者自己设计的一个语法结构,是作者人工设定的,个人认为他当时可能认为null判断为object,更符合其他语言对于null的理解吧,因为有些语言设定null是空值,是一个空指针,逻辑上null表示一个空对象的指针,一般表示一个变量定义了但是值为空。容易让学习过其他语言的人在学习JS时好理解。但JS底层中实际不是这么去定义这个null的。
所以一般存在null的时候,要么本来这个变量就是null,要么是你主动申明一个变量值为null。
undefined
主要出现在以下情况:
- 变量申明了但没赋值, 或者根本不声明但直接使用;
let a
console.log(a) // undefined
console.log(b) // undefined
- 一个函数为空,但函数其实是默认会返回东西的,执行的时候就返回undefined;
function fn (){}
console.log(fn()) // undefined
- 函数的形参没给值;
function fn(a, b){console.log(a, b)}
fn(1) // 1, undefined
- 对象找不到这个属性;
let obj = {}
console.log(obj.a) // undefined
这些情况对于一个初学者来说不用死记,视频中提到只要知道一个关键词:被动。
视频中说只要找不到值,JS就会被迫的给你个undefined。你再看看上面的情况就知道了。
但是嘞!你以这样的回答去面试肯定是不行滴,因为一般面试会问你上面说的第四种情况,这时候你需要了解什么是原型链【JS基础】浅谈个人对JS原型对象和原型链的理解(不定期更正),这才是正统的解释,用这个去回答就ok了。
然后嘞,上面的情况3原因也是原型链,情况1是变量提升的原因,至于情况2是因为函数没有返回出东西,所以log一脸懵逼,就给出了个undefined
在JS的底层中undefined是个特殊对象,所以不支持隐式转换。你Number(undefined)
、1+undefined
都会是个NaN
。
好,那如果我们像null一样主动去给值undefined呢?其实会写了个寂寞,相当于没写。在函数中也是一样的:
function fn(a, b=5){
console.log(a,b)
}
fn(21, undefined) // 打印21和5
解构赋值也是:
let [a, b=2] = [1, undefined]
console.log(a, b) // 1, 2
所以,平时写一个变量为空时,尽量写null吧;
undefined这个基本类型是JS设计时自己创建特有的,当然其他语言也可以自己手动定义,不过这样就钻牛角尖了。本质是不一样的,一个官方语言底层的设计支持,一个是个人手动添加,还需要添加各种特性,且并不属于官方语言的设计规范。而且照这种逻辑想法,所有高级语言都能实现新增其他的基本类型了。
用void 0代替undefined
在一些大公司里可能会要求用void 0代替undefined,void的语法规则是无论后面跟什么都返回undefined,简写就void 0。
这是因为首先undefined很特殊,他其实是直接挂在window上的
“undefined” in window // true
当我们在函数作用域中:
let undefined = 1
console.log(undefined)
是能够直接改变undefined的值的,所以严格的话要这样:
let undefined = void 0