详解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 相关文章推荐
高效的获取当前元素是父元素的第几个子元素
Oct 15 Javascript
jquery checkbox实现单选小例
Nov 27 Javascript
常见的jQuery选择器汇总
Nov 24 Javascript
jQuery简单实现验证邮箱格式
Jul 15 Javascript
JS实现黑色风格的网页TAB选项卡效果代码
Oct 09 Javascript
原生JavaScript实现AJAX、JSONP
Feb 07 Javascript
Vue2路由动画效果的实现代码
Jul 10 Javascript
Vue插件从封装到发布的完整步骤记录
Feb 28 Javascript
Vue实现兄弟组件间的联动效果
Jan 21 Javascript
微信小程序实现滑动操作代码
Apr 23 Javascript
Vue中nprogress页面加载进度条的方法实现
Nov 13 Javascript
el-table-column 内容不自动换行的解决方法
Aug 14 Vue.js
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 5昨天隆重推出--PHP 5/Zend Engine 2.0新特性
2006/10/09 PHP
网站当前的在线人数
2006/10/09 PHP
PHP判断搜索引擎蜘蛛并自动记忆到文件的代码
2012/02/04 PHP
WordPress自定义时间显示格式
2015/03/27 PHP
PHP目录与文件操作技巧总结(创建,删除,遍历,读写,修改等)
2016/09/11 PHP
javascript 24小时弹出一次的代码(利用cookies)
2009/09/03 Javascript
子窗口、父窗口和Silverlight之间的相互调用
2010/08/16 Javascript
13个绚丽的Jquery 界面设计网站推荐
2010/09/28 Javascript
使用jquery mobile做幻灯播放效果实现步骤
2013/01/04 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
jquery动态分页效果堪比时光网
2014/09/25 Javascript
Jquery的基本对象转换和文档加载用法实例
2015/02/25 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
如何防止JavaScript自动插入分号
2015/11/05 Javascript
实例详解JavaScript获取链接参数的方法
2016/01/01 Javascript
jQuery Chosen通用初始化
2017/03/07 Javascript
jQuery实现多张图片上传预览(不经过后端处理)
2017/04/29 jQuery
vue实现一个移动端屏蔽滑动的遮罩层实例
2017/06/08 Javascript
在vue中使用echarts图表实例代码详解
2018/10/22 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
2020/07/19 Javascript
Vue props中Object和Array设置默认值操作
2020/07/30 Javascript
[48:51]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第一场 11.28
2020/12/02 DOTA
python中map()函数的使用方法示例
2017/09/29 Python
Python2和Python3之间的str处理方式导致乱码的讲解
2019/01/03 Python
python实现图片压缩代码实例
2019/08/12 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
2020/11/01 Python
如何转换一个字符串到enum值
2014/04/12 面试题
大学毕业生通用求职信
2013/09/28 职场文书
母亲节感恩寄语
2014/02/21 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
python实战之一步一步教你绘制小猪佩奇
2021/04/22 Python
python实现三阶魔方还原的示例代码
2021/04/28 Python
关于Vue Router的10条高级技巧总结
2021/05/06 Vue.js
详解Mysq MVCC多版本的并发控制
2022/04/29 MySQL