详解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 相关文章推荐
权威JavaScript 中的内存泄露模式
Aug 13 Javascript
仅Firefox中链接A无法实现模拟点击以触发其默认行为
Jul 31 Javascript
JS读取XML文件示例代码
Nov 15 Javascript
关于jquery中全局函数each使用介绍
Dec 10 Javascript
Jquery解析Json格式数据过程代码
Oct 17 Javascript
jquery实现的缩略图预览滑块实例
Jun 25 Javascript
drag-and-drop实现图片浏览器预览
Aug 06 Javascript
详细解读JavaScript的跨浏览器事件处理
Aug 12 Javascript
JavaScript实现打开链接页面的方式汇总
Jun 02 Javascript
全面解析JavaScript中“&&”和“||”操作符(总结篇)
Jul 18 Javascript
Javascript基于jQuery UI实现选中区域拖拽效果
Nov 25 Javascript
bootstrap table动态加载数据示例代码
Mar 25 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
晋城吧对DiscuzX进行的前端优化要点
2010/09/05 PHP
PHP学习笔记(一) 简单了解PHP
2014/08/04 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
PHP环境中Memcache的安装和使用
2015/11/05 PHP
关于UTF-8的客户端用AJAX方式获取GB2312的服务器端乱码问题的解决办法
2010/11/30 Javascript
js时间日期和毫秒的相互转换
2013/02/22 Javascript
js简单实现删除记录时的提示效果
2013/12/05 Javascript
代码触发js事件(click、change)示例应用
2013/12/13 Javascript
checkbox选中与未选中判断示例
2014/08/04 Javascript
深入php面向对象、模式与实践
2016/02/16 Javascript
关于jQuery EasyUI 中刷新Tab选项卡后一个页面变形的解决方法
2017/03/02 Javascript
javascript 开发之百度地图使用到的js函数整理
2017/05/19 Javascript
Vue.js结合Ueditor富文本编辑器的实例代码
2017/07/11 Javascript
微信小程序生成分享海报方法(附带二维码生成)
2019/03/29 Javascript
JavaScript 扩展运算符用法实例小结【基于ES6】
2019/06/17 Javascript
JS中FileReader类实现文件上传及时预览功能
2020/03/27 Javascript
Python写的一个定时重跑获取数据库数据
2016/12/28 Python
从头学Python之编写可执行的.py文件
2017/11/28 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
python脚本当作Linux中的服务启动实现方法
2019/06/28 Python
Python Numpy库常见用法入门教程
2020/01/16 Python
浅谈spring boot 集成 log4j 解决与logback冲突的问题
2020/02/20 Python
在主流系统之上安装Pygame的方法
2020/05/20 Python
Python基于gevent实现文件字符串查找器
2020/08/11 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
Rockport乐步美国官网:风靡美国的白宫鞋
2016/11/24 全球购物
.NET面试10题
2014/02/24 面试题
内容编辑个人求职信
2013/12/10 职场文书
会议邀请书范文
2014/02/02 职场文书
社区庆中秋节活动方案
2014/02/07 职场文书
感恩父母的演讲稿
2014/05/06 职场文书
优秀大学生自荐信
2014/06/09 职场文书
教师反腐倡廉演讲稿
2014/09/03 职场文书
机关干部四风问题自我剖析及整改措施
2014/10/26 职场文书
高中团支书竞选稿
2015/11/21 职场文书
2016年学校爱国卫生月活动总结
2016/04/06 职场文书