一、引言
undefined和null在使用上还是存在许多相似性的,在if语句中,两者都会被自动转为false,相等运算符(==)甚至直接报告两者相等。
undefined == null
// true
至于两者为什么相等,看了一下《JS高级程序设计》和《你不知道的JS》,似乎都只提到了是规则,网上的解释也都是个人的看法,以后在哪里看到了再回来补上:
以下摘自《你不知道的JS》
再回到undefined和null,为什么要同时存在两个表示“无”的值呢,看阮一峰的博客发现大神早就说过这个历史问题了。1995年JavaScript诞生时,最初像Java一样,只设置了null作为表示"无"的值。根据C语言的传统,null被设计成可以自动转为0。
但是,JavaScript的设计者Brendan Eich,觉得这样做还不够,有两个原因。
首先,null像在Java里一样,被当成一个对象。但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示"无"的值最好不是对象。
其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null
自动转为0,很不容易发现错误。
因此,Brendan Eich又设计了一个undefined
。
二、区别
从逻辑角度看:
- null值表示一个空对象指针,或者说表示"没有对象",即该处不应该有值。若定义的变量准备在将来用于保存对象,那么可以将该变量初始化为null而不是其他值。
-
undefined表示未定义,或者说“缺少值”,就是说此处应该有一个值,但是还没有定义,典型的情况是
- 变量被声明了,但没有赋值时,就等于undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于undefined。
- 对象没有赋值的属性,该属性的值为undefined。
- 函数没有返回值时,默认返回undefined。
从使用场景上看:
- null可以作为函数的参数,调用函数时,某个参数未设置任何值,这时就可以传入null,表示该参数为空;可以作为对象原型链的终点;可以用于解除引用,以便垃圾回收;
- 而无论什么情况下,都没有必要把一个变量的值显式地设置为undefined。
从其他方面看:
typeof undefined; // "undefined"
typeof null; // "object"
Number(undefined); // NaN
Number(null); // 0
......
顺便插一句,为什么typeof null的值是"object" ?
这只是 JS 存在的一个悠久 Bug。不同的对象在底层的存储是用二进制表示的。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,如果二进制的前三位都为0,系统会判定是object类型。然而 null 表示为全零,其存储二进制正是000,所以系统会判定是object类型。