这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
前言
本系列将分多篇文章介绍 js 相关的“冷门知识”,这里的“冷门知识”是指大部分开发者都不曾留意过的知识点,亦或者是意料不到的知识点。这些知识点对现实中的面试、开发也许没有很大的帮助,甚至压根没任何用处,但希望以此博得大家一乐,并额外拓展下知识面。
本系列文章的大部分知识参考于阮一峰写的“网道 - 互联网开发文档 (wangdoc.com)”,强烈建议 web 前端开发者都看下这份文档,既是入门的好帮手,也是拓展知识面的利器。
本系列文章的任何参考,均会在文末标出。
文章示例均是经过本人验证,如有错漏,请在评论区指正。
null 与 undefined 为何要兼得
做过开发的都知道,动态类型语言也好,静态类型语言也好,它都需要有一个用来表示“无”的东西,如:java 的 null
,python 的 None
等等。
在 js 里,也有表示“无”的东西,而且是两个, null
和 undefined
。为什么会有两个表示“无”的数据类型呢?
其实这与历史有关。
在第一版的 js 里,js 的设计者 Brendan Eich 设计了 null
,但后来他认为仅有 null
来表示“无”是不够的,原因有以下两个:
- Brendan Eich 认为 js 分为原始类型和复合类型(对象、数组、函数统称为复合类型(complex)),表示“无”的值最好不是对象,但是起初设计的
null
会被 js 当成一个对象。
typeof null // "object"
null
可以被Number()
函数转化为 0,而 js 的“自动转换类型”就是使用到了Number()
函数,Brendan Eich 觉得null
会自动转化为 0,由于最初的 js 并没有错误处理机制,不容易发现错误。
var obj = null
1 + obj // 结果等于 1,而不是 1[object Object]
于是,Brendan Eich 决定新增了一个表示“无”的数据类型 undefined
。
undefined
,这个单词我们都知道是表示“未定义”或“未声明”,如果一个变量没有声明,它的值是 undefined
,而不是 null
。
undefined
会被typeof
判断为"undefined"
typeof undefined // "undefined"
Number()
函数会将undefined
转为NaN
。
Number(undefined) // NaN
我们直接看看别人是怎么解读 null
和 undefined
。
外国的牛人 Axel Rauschmayer 是这样解读:
null
means “no object.” It is used as a nonvalue whenever an object is expected (parameters, last in a chain of objects, etc.).
undefined
means “no value.” Uninitialized variables areundefined
而阮一峰是这样解读:
null表示"没有对象",即该处不应该有值。
undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。
这里,Axel Rauschmayer 和 阮一峰 都解读得很准确了,我没必要再去解读了。
有关 null 与 undefined 的问题
null == undefined 判断为 true?
没错,如果你用不严格相等运算符来比较 null
和 undefined
,程序认为它们俩是相等的。但是如果你用严格相等运算符来进行判断,程序认为它们不是等同的。
null == undefined // true
null === undefined // false
我在 twitter 也挖出了 js 设计者 Brendan Eich 的对 null
和 undefined
的一些回答。我英文不好,自己的见解仅供参考(下面个人见解也仅供参考,请更多参考 Brendan Eich 原来的回答)。
根据 Brendan Eich 的回答,大概是这样的。
null
和 undefined
在 js ==
下是认为来自等价类型(class 应该不是翻译为“类”吧,应该是指“类型”)
为什么 null 在 js 里使用如此困难
我不明白作者说的这段话与问题有什么关联,感觉有点不太对劲......
Brendan Eich 并不喜欢 null 和 undefined 的设计
事实上,Brendan Eich 自己压根就不喜欢 null
和 undefined
的设计,当时只是为了应付“网景”高层,才让 js 变得像 java 一样(Brendan Eich 不喜欢 java)。Brendan Eich 在 twitter 还特别说明他更倾向于“一切都是对象”的设计,这样就不会存在布尔、数字、字符串包装器,以及 undefined 和 null。
补充:js 的不合理基本都是历史原因造成
有关 js 的历史,我认为每个前端人员都应该去了解一下,对比其他语言,js 为什么在一些地方会显得这么奇怪,其实都是与历史有关。
建议看下这篇文章 Javascript诞生记 - 阮一峰的网络日志 (ruanyifeng.com)。
总结
null
null
是一个特殊的数据类型,但它会被typeof
判断为对象,可是null
并没有任何的对象属性和方法(如:toString)。
typeof null // "object"
null.toString() // Uncaught TypeError: Cannot read property 'toString' of null
// 但是 instanceof 不认为 null 是 Object 的构造函数实例
null instanceof Object // false
null
在自动转换数据类型的场景下,会被自动转换为 0。
1 + null // 等于 1,并非 1[object Object]
null
表示"没有对象",即该处不应该有值。(阮一峰的总结)
undefined
undefined
是一个特殊的数据类型,它会被typeof
判断为undefined
。
typeof undefined // "undefined"
undefined
会被Number()
函数转为NaN
。
Number(undefined) // NaN
// 因此
1 + undefined // NaN
undefined
表示"缺少值",就是此处应该有一个值,但是还没有定义。(阮一峰的总结)
参考
- null, undefined 和布尔值 - JavaScript 教程 - 网道 (wangdoc.com)
- undefined与null的区别 - 阮一峰的网络日志 (ruanyifeng.com)
- Javascript诞生记 - 阮一峰的网络日志 (ruanyifeng.com)
- Dr. Axel Rauschmayer 写的 《Speaking JavaScript》 - Chapter 1. Basic JavaScript (speakingjs.com)
- Brendan Eich 的 twitter: 为什么
null == undefined
等于 true - Brendan Eich 的 twitter: 不喜欢 js 的数据类型设计
吐槽一下,阮一峰真的很喜欢看 Dr. Axel Rauschmayer 写的书,网道的内容有很多都是参考 Axel Rauschmayer 写的内容。
只有站在巨人肩上的人才有可能看到更远的景色。
“js 冷门知识”系列文章推荐
关注专栏,认识更多的 js 冷门知识。