详解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 Select操作大集合
May 26 Javascript
cnblogs中在闪存中屏蔽某人的实现代码
Nov 14 Javascript
从零学JS之你需要了解的几本书
May 19 Javascript
Html5的placeholder属性(IE兼容)实现代码
Aug 30 Javascript
jquery实现增加删除行的方法
Feb 03 Javascript
简介JavaScript中的italics()方法的使用
Jun 08 Javascript
vue实现简单表格组件实例详解
Apr 16 Javascript
JS简单获取当前日期和农历日期的方法
Apr 17 Javascript
Angular实现点击按钮后在上方显示输入内容的方法
Dec 27 Javascript
JS module的导出和导入的实现代码
Feb 25 Javascript
JS+CSS实现随机点名(实例代码)
Nov 04 Javascript
jquery实现穿梭框功能
Jan 19 jQuery
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
php5 and xml示例
2006/11/22 PHP
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
PHP实现模仿socket请求返回页面的方法
2014/11/04 PHP
CodeIgniter配置之SESSION用法实例分析
2016/01/19 PHP
PHP实现类似于C语言的文件读取及解析功能
2017/09/01 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
2018/02/06 PHP
使用TextRange获取输入框中光标的位置的代码
2007/03/08 Javascript
利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解
2010/07/24 Javascript
Javascript计算时间差的函数分享
2011/07/04 Javascript
js如何判断不同系统的浏览器类型
2013/10/28 Javascript
html的DOM中document对象anchors集合用法实例
2015/01/21 Javascript
深入理解jQuery中的事件冒泡
2016/05/24 Javascript
详解Sea.js中Module.exports和exports的区别
2017/02/12 Javascript
js下载文件并修改文件名
2017/05/08 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
Vue验证码60秒倒计时功能简单实例代码
2018/06/22 Javascript
nodejs通过钉钉群机器人推送消息的实现代码
2019/05/05 NodeJs
Layui事件监听的实现(表单和数据表格)
2019/10/17 Javascript
基于Vue实现微前端的示例代码
2020/04/24 Javascript
Nodejs + sequelize 实现增删改查操作
2020/11/07 NodeJs
[34:41]夜魇凡尔赛茶话会 第二期02:你画我猜
2021/03/11 DOTA
Python fileinput模块使用介绍
2014/11/30 Python
浅谈终端直接执行py文件,不需要python命令
2017/01/23 Python
Python3.6 Schedule模块定时任务(实例讲解)
2017/11/09 Python
Python selenium抓取微博内容的示例代码
2018/05/17 Python
Django中从mysql数据库中获取数据传到echarts方式
2020/04/07 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
2020/09/14 Python
Python爬虫代理池搭建的方法步骤
2020/09/28 Python
利用HTML5的新特点实现图片文件异步上传
2014/05/29 HTML / CSS
英国领先的在线旅游和休闲零售商:lastminute.com
2019/01/23 全球购物
ktv总经理岗位职责
2014/02/17 职场文书
提拔干部考察材料
2014/05/26 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
Pytorch 如何加速Dataloader提升数据读取速度
2021/05/28 Python
css3属性选择器 “~”(波浪号) “,”(逗号) “+”(加号)和 “>”(大于号)
2022/04/19 HTML / CSS
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL