在JavaScript中,将一个变量赋值为undefined或null,感觉没啥区别,都表示“无”;但在实际应用中,远非如此,这两个之间区别的不明确可能会导致一些问题。

这篇文章中,我已经简略介绍了undefinednull的特性了。

本文将探讨JavaScript中undefinednull之间的相似和差异之处。

相似性

(1)undefinednull在if语句中,都会被自动转为false,加!转换为true,相等运算符对于两者比较是相等的。

if (!undefined) 
console.log('undefined is false');
// undefined is false

if (!null)
console.log('null is false');
// null is false

undefined == null
// true

(2)在JavaScript中,只有六个falsy值,nullundefined都包含在六个falsy值中,当进行逻辑判断时所有的Falsy值均为false。

  • false
  • 0
  • ‘’ (空字符串,’’和””一样)
  • null
  • undefined
  • NaN

除了这六个值,JavaScript中的任何其他值都被认为是truthy值,当进行逻辑判断时均为true。

(3)同样在JavaScript中,有六个原始值,nullundefined都包含在这六个原始值中。

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol

既然undefinednull的含义与用法都比较相似,那为什么还要无端增加另外一个值,这不是增加混淆吗?

历史原因

最近,在阅读阮一峰老师的博客文章时,才从历史因素里得到答案!

1995年JavaScript诞生之初,像Java一样,只设置了null作为表示”无”的值。

根据C语言的传统,null被设计成可以自动转为0。

Number(null)
// 0

6 + null
// 6

但是,JavaScript的设计者Brendan Eich,觉得这样做达不到自己的预想,其中有两个原因。

首先,null像在Java里一样,被当成一个对象。但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示”无”的值最好不是对象。

其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null自动转为0,很不容易发现错误。

因此,Brendan Eich又设计增加了一个undefined

差异性

(1)数据类型区别

undefined类型只有一个值,undefined;null类型只有一个值,null。

也就是说undefined值和null值分别属于不同的数据类型,并且这两个数据类型都只有一个值,使用“typeof”运算符判断类型。

console.log(typeof undefined);  // undefined
console.log(typeof null); // object

第一行输出没毛病,正确打印出undefined类型;而第二行打印结果为object,难道null不是null类型?

原因解释:这是JS一个设计失误,原本正确的结果应该是null,现在只能将错就错,或许以后哪个新版本会修正此问题。

(2)转为数值区别

JavaScript的最初版本为了更好区分这两个值,是这样设定的:null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN

var a1= 5 + null;
console.log(a1) // 5

var a2= 5 + undefined;
console.log(a2) // NaN

(3)null !== undefined

如上所见,nullundefined不同,但有一些相似之处, 因此,ECMAScript规范规定null不严格等于undefined

null !== undefined  // true

null === undefined // false

但是,上面也提到了,null松散相等于undefined(相比===的相等程度更低)。

null == undefined  // true

在JavaScript中,==适用松散相等,意味着我们在将它们转换为通用类型后比较两个值。

只要记住null==undefined会返回true,因为它们是类似的值;但null===undefined会返回false,因为它们是不同类型的值。后续也会增加==与===区别的文章,敬请期待。

实际用法

但是,上面的区分,在实践中都不常用。实际上,nullundefined被视为几乎同义的,只有一些细小的差别。

null表示一个变量被人为的设置为空对象,而不是原始状态,即该处不应该有值。一般会在以下 2 种场景中出现:

(1) 利用document.getElementById(‘XXX’) 寻找一个不存在的元素,将返回null。

console.log(null == document.getElementById('notExistElement'))  // true

(2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype)  // null

undefined表示一个变量自然的、最原始的状态值,就是此处应该有一个值,但是还没有定义。一般会在以下 4 种场景中出现:

(1)声明了一个变量,但没有赋值,就等于undefined

var a
console.log(a) // undefined

(2) 函数定义了形参,但没有传递实参,该参数等于undefined

//函数定义了形参 a 
function f(a) {
console.log(a); // undefined
}
f(); //未传递实参

(3)访问对象上不存在的属性,该属性的值为undefined

var  a = new Object()
a.p // undefined

(4)函数没有返回值时,默认返回undefined

var a = f()
a // undefined

所以,在实际使用过程中,为了保证变量所代表的语义,不要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。

最后引用玉伯大大对null和undefined的解释:

值类型的“虚无”用undefined,引用类型的“虚无”,用null

本人Github链接如下,欢迎各位Star

https://github.com/miqilin21/miqilin21.github.io



JavaScript      JavaScript

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!