详解JavaScript中undefined与null的区别


Posted in Javascript onMarch 29, 2014

有点奇怪的是,JavaScript语言居然有两个表示"无"的值:undefined和null。这是为什么?

一、相似性
在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别。

var a = undefined;
var a = null;

上面代码中,a变量分别被赋值为undefined和null,这两种写法几乎等价。
undefined和null在if语句中,都会被自动转为false,相等运算符甚至直接报告两者相等。

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

上面代码说明,两者的行为是何等相似!
既然undefined和null的含义与用法都差不多,为什么要同时设置两个这样的值,这不是无端增加JavaScript的复杂度,令初学者困扰吗?Google公司开发的JavaScript语言的替代品Dart语言,就明确规定只有null,没有undefined!
二、历史原因
最近,我在读新书《Speaking JavaScript》时,意外发现了这个问题的答案!
原来,这与JavaScript的历史有关。1995年JavaScript诞生时,最初像Java一样,只设置了null作为表示"无"的值。
根据C语言的传统,null被设计成可以自动转为0。

Number(null)
// 0
5 + null
// 5

但是,JavaScript的设计者Brendan Eich,觉得这样做还不够,有两个原因。
首先,null像在Java里一样,被当成一个对象。

typeof null
// "object"

但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示"无"的值最好不是对象。
其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null自动转为0,很不容易发现错误。
因此,Brendan Eich又设计了一个undefined。
三、最初设计
JavaScript的最初版本是这样区分的:null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

Number(undefined)
// NaN
5 + undefined
// NaN

四、目前的用法
但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。
null表示"没有对象",即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype)
// null

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。

var i;
i // undefined
function f(x){console.log(x)}
f() // undefined
var  o = new Object();
o.p // undefined
var x = f();
x // undefined

Javascript 相关文章推荐
一张表格告诉你windows.onload()与$(document).ready()的区别
May 16 Javascript
jquery实现textarea输入框限制字数的方法
Jan 15 Javascript
jQuery实现的表头固定效果实例【附完整demo源码下载】
Aug 01 Javascript
详谈表单格式化插件jquery.serializeJSON
Jun 23 jQuery
使用重写url机制实现验证码换一张功能
Aug 01 Javascript
vue使用drag与drop实现拖拽的示例代码
Sep 07 Javascript
vue.js整合vux中的上拉加载下拉刷新实例教程
Jan 09 Javascript
Vue + better-scroll 实现移动端字母索引导航功能
May 07 Javascript
vue表单自定义校验规则介绍
Aug 28 Javascript
JS中DOM元素的attribute与property属性示例详解
Sep 04 Javascript
浅谈javascript如何获取文件后缀名
Aug 07 Javascript
elementUI同一页面展示多个Dialog的实现
Nov 19 Javascript
JQuery解析HTML、JSON和XML实例详解
Mar 29 #Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
Mar 28 #Javascript
javascript修改IMG标签的src问题
Mar 28 #Javascript
JS将光标聚焦在文本最后的实现代码
Mar 28 #Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
Mar 28 #Javascript
JavaScript调用ajax获取文本文件内容实现代码
Mar 28 #Javascript
js如何调用qq互联api实现第三方登录
Mar 28 #Javascript
You might like
PHP、Python和Javascript的装饰器模式对比
2015/02/03 PHP
PHP使用内置函数file_put_contents写入文件及追加内容的方法
2015/12/07 PHP
漂亮的widgets,支持换肤和后期开发新皮肤(2007-4-27已更新1.7alpha)
2007/04/27 Javascript
jQuery实现的类flash菜单效果代码
2010/05/17 Javascript
JavaScript 错误处理与调试经验总结
2010/08/10 Javascript
JavaScript日历实现代码
2010/09/12 Javascript
js 三级关联菜单效果实例
2013/08/13 Javascript
js 时间格式与时间戳的相互转换示例代码
2013/12/25 Javascript
JS 日期比较大小的简单实例
2014/01/13 Javascript
js获取checkbox值的方法
2015/01/28 Javascript
Jquery简单分页实现方法
2015/07/24 Javascript
js实现的下拉框二级联动效果
2016/04/30 Javascript
JS实现图片的不间断连续滚动的简单实例
2016/06/03 Javascript
微信小程序 实战程序简易新闻的制作
2017/01/09 Javascript
vue.js实现单选框、复选框和下拉框示例
2017/07/18 Javascript
js实现可以点击收缩或张开的悬浮窗
2017/09/18 Javascript
解决ie img标签内存泄漏的问题
2017/10/13 Javascript
jquery ajax异步提交表单数据的方法
2017/10/27 jQuery
clipboard.js在移动端复制失败的解决方法
2018/06/13 Javascript
Vue CLI3 如何支持less的方法示例
2018/08/29 Javascript
JS自定义右键菜单实现代码解析
2020/07/16 Javascript
Openlayers实现地图的基本操作
2020/09/28 Javascript
python 获取本机ip地址的两个方法
2013/02/25 Python
python中使用pyhook实现键盘监控的例子
2014/07/18 Python
基于Django的ModelForm组件(详解)
2017/12/07 Python
Python 3.8 新功能大揭秘【新手必学】
2020/02/05 Python
python词云库wordCloud使用方法详解(解决中文乱码)
2020/02/17 Python
Django单元测试中Fixtures用法详解
2020/02/25 Python
Python虚拟环境的创建和使用详解
2020/09/07 Python
《草虫的村落》教学反思
2014/02/16 职场文书
银行授权委托书样本
2014/10/13 职场文书
实习单位证明范例
2014/11/17 职场文书
优秀教师先进材料
2014/12/16 职场文书
硕士毕业答辩开场白
2015/05/27 职场文书
房贷工资证明范本
2015/06/12 职场文书
交通事故协议书范本
2016/03/19 职场文书