详解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 替换
Feb 19 Javascript
Aptana调试javascript图解教程
Nov 30 Javascript
各情景下元素宽高的获取实现代码
Sep 13 Javascript
禁用页面部分JavaScript方法的具体实现
Jul 31 Javascript
JQUERY dialog的用法详细解析
Dec 19 Javascript
JQuery实现样式设置、追加、移除与切换的方法
Jun 11 Javascript
JavaScript实现Fly Bird小游戏
Dec 15 Javascript
Angularjs自定义指令实现分页插件(DEMO)
Sep 16 Javascript
利用jQuery+localStorage实现一个简易的计时器示例代码
Dec 25 jQuery
JavaScript工具库之Lodash详解
Jun 15 Javascript
ES6模板字符串和标签模板的应用实例分析
Jun 25 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
Jun 11 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
解决CodeIgniter伪静态失效
2014/06/09 PHP
Yii框架上传图片用法总结
2016/03/28 PHP
PHP模板引擎Smarty中的保留变量用法分析
2016/04/11 PHP
PHP中for循环与foreach的区别
2017/03/06 PHP
php创建图像具体步骤
2017/03/13 PHP
JavaScript 乱码问题
2009/08/06 Javascript
JavaScript 事件冒泡简介及应用
2010/01/11 Javascript
js 面向对象的技术创建高级 Web 应用程序
2010/02/25 Javascript
Javascript 通过json自动生成Dom的代码
2010/04/01 Javascript
jquery下json数组的操作实现代码
2010/08/09 Javascript
JS焦点图切换,上下翻转
2011/05/12 Javascript
Prototype源码浅析 Number部分
2012/01/16 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
2015/03/04 Javascript
JS简单实现城市二级联动选择插件的方法
2015/08/19 Javascript
JavaScript编写九九乘法表(两种任选)
2017/02/04 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
关于定制FileField中的上传文件名称问题
2017/08/22 Javascript
利用js将ajax获取到的后台数据动态加载至网页中的方法
2018/08/08 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
[44:21]Ti4 循环赛第四日 附加赛NEWBEE vs LGD
2014/07/13 DOTA
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
Python利用IPython提高开发效率
2016/08/10 Python
Python金融数据可视化汇总
2017/11/17 Python
python opencv3实现人脸识别(windows)
2018/05/25 Python
Python Grid使用和布局详解
2018/06/30 Python
pip 安装库比较慢的解决方法(国内镜像)
2019/10/06 Python
python 模拟登陆github的示例
2020/12/04 Python
python函数超时自动退出的实操方法
2020/12/28 Python
浅析CSS3 中的 transition,transform,translate之间区别和作用
2020/03/26 HTML / CSS
阿联酋网上花店:Ferns N Petals
2018/02/14 全球购物
教育课题研究自我鉴定范文
2013/12/28 职场文书
财经学院自荐信范文
2014/02/02 职场文书
知名企业招聘广告词大全
2014/03/18 职场文书
2014领导班子四风问题查摆思想汇报
2014/09/13 职场文书
2014党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
小程序实现文字循环滚动动画
2021/06/14 Javascript