参考链接
null 与 undefined
总的来说,
null 表示一个 “空值” 的对象,但它不是一个空对象,因为它根本就没有属性;
undefined 表示 “缺少值”,就是此处应该有一个值,但是还没有定义。
主要区别就是,null 表示有值但为空,undefined 表示没有值。
关于它们的一些具体表现,比如说转为数值的时候,null 转为 0,undefined 转为 NaN;
使用 typeof 的时候,会分别返回 null 和 undefined。
区别表现
转为数值
Number(null) // 05 + null // 5Number(undefined) // NaN5 + undefined // NaN
两者不严格相等
undefined == null // trueundefined === null // false
使用 **typeof**
typeof null // 'object'typeof undefined // 'undefined'
典型场景
**null** 表示 “空” 的对象,即该处不应该有值。典型场景是:
(1)作为函数的参数,表示该函数的参数不是对象。
(2)作为对象原型链的终点。
**undefined** 表示 “缺少值”,就是此处应该有一个值,但是还没有定义。典型场景是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2)调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
使用
**null** 表示一个值被定义了,定义为“空值”;
**undefined** 表示根本不存在定义。
所以设置一个值为 null 是合理的,如 objA.valueA = null;
但设置一个值为 undefined 是不合理的
objA.valueA = undefined; // 应该直接使用 delete objA.valueA;
任何一个存在引用的变量值为 undefined 都是一件错误的事情。
这样判断一个值是否存在,就可以用
objA.valueA === undefined // 不应使用 null
因为 undefined == null(不是严格相等),而 null 表示该值定义为空值。
其他
为什么
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' 的原因。
为什么
==和===对比会出现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 的源码。
为什么
let undefiend = 'test'可以覆盖掉 JavaScript 自身的undefined?
function test(n) {let undefined = 'test'return n === undefined}test() // falsetest(undefined) // falsetest('test') // turelet undefined = 'test' // Uncaught SyntaxError: Identifier 'undefined' has already been declared
JavaScript 对于 undefined 的限制方式为全局创建了一个只读的 undefined ,但是并没有彻底禁止局部 undefined 变量的定义。
据说在 JavaScript 高版本禁止了该操作,但我没有准确的依据。
请在任何时候,都不要进行 undefined 变量的覆盖,就算是你的 JSON 转换将 undefined 转换为 '' 。也不要通过该操作进行,这将是及其危险的行为。
