详解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 相关文章推荐
js中巧用cssText属性批量操作样式
Mar 13 Javascript
JS编程小常识很有用
Nov 26 Javascript
javascript学习笔记(三)BOM和DOM详解
Sep 30 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
Mar 29 Javascript
jquery实现界面无刷新加载登陆注册
Jul 30 Javascript
用js屏蔽被http劫持的浮动广告实现方法
Aug 10 Javascript
一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)
Jan 08 Javascript
php中and 和 &&出坑指南
Jul 13 Javascript
Vue.js 时间转换代码及时间戳转时间字符串
Oct 16 Javascript
layUI实现列表查询功能
Jul 27 Javascript
Weex开发之WEEX-EROS开发踩坑(小结)
Oct 16 Javascript
微信小程序实现滑动翻页效果(完整代码)
Dec 06 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
DOTA2【瓜皮时刻】Vol.91 RTZ山史最惨“矿难”
2021/03/05 DOTA
Laravel中前端js上传图片到七牛云的示例代码
2017/09/04 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
javascript之解决IE下不渲染的bug
2007/06/29 Javascript
9个JavaScript评级/投票插件
2010/01/18 Javascript
Jquery截取中文字符串的实现代码
2010/12/22 Javascript
JavaScript 变量作用域分析
2011/07/04 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
js阻止默认事件与js阻止事件冒泡示例分享 js阻止冒泡事件
2014/01/27 Javascript
jQuery中nextUntil()方法用法实例
2015/01/07 Javascript
JavaScript淡入淡出渐变简单实例
2015/08/06 Javascript
node.js爬虫爬取拉勾网职位信息
2017/03/14 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
2017/08/22 Javascript
图片懒加载imgLazyLoading.js使用详解
2020/09/15 Javascript
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
从源码里了解vue中的nextTick的使用
2018/11/22 Javascript
vue实现按需加载组件及异步组件功能
2019/05/27 Javascript
Vue Router的手写实现方法实现
2020/03/02 Javascript
JavaScript享元模式原理与用法实例详解
2020/03/09 Javascript
JavaScript函数重载操作实例浅析
2020/05/02 Javascript
[02:52]2017DOTA2国际邀请赛中国区预选赛晋级之路
2017/07/03 DOTA
[01:30:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第二场 2月2日
2021/03/11 DOTA
在Python的gevent框架下执行异步的Solr查询的教程
2015/04/16 Python
Python实现二分查找与bisect模块详解
2017/01/13 Python
详解pandas DataFrame的查询方法(loc,iloc,at,iat,ix的用法和区别)
2019/08/02 Python
flask 实现上传图片并缩放作为头像的例子
2020/01/09 Python
瑞典领先的汽车零部件网上零售商:bildelaronline24.se
2017/01/12 全球购物
英国最大的自有市场,比亚马逊便宜:Flubit
2019/03/19 全球购物
Paul Smith英国官网:英国国宝级时装品牌
2019/03/21 全球购物
简述DNS进行域名解析的过程
2013/12/02 面试题
考试没考好检讨书
2014/01/31 职场文书
乡镇爱国卫生月活动总结
2014/06/25 职场文书
会议欢迎标语
2014/06/30 职场文书
商场周年庆活动方案
2014/08/19 职场文书
大学生党校培训心得体会
2014/09/11 职场文书
Vue2项目中对百度地图的封装使用详解
2022/06/16 Vue.js