详解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 相关文章推荐
sina的lightbox效果。
Jan 09 Javascript
js 静态动态成员 and 信息的封装和隐藏
May 29 Javascript
js防止表单重复提交实现代码
Sep 05 Javascript
jQuery插件slick实现响应式移动端幻灯片图片切换特效
Apr 12 Javascript
JavaScript构造函数详解
Dec 27 Javascript
微信小程序前端源码逻辑和工作流
Sep 25 Javascript
Vue.js组件tab实现选项卡切换
Mar 23 Javascript
vue-cli配置文件——config篇
Jan 04 Javascript
关于vue的语法规则检测报错问题的解决
May 21 Javascript
JavaScript写个贪吃蛇小游戏(超详细)
Mar 17 Javascript
简单了解Vue computed属性及watch区别
Jul 10 Javascript
javascript canvas实现简易时钟例子
Sep 05 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
php中的观察者模式
2010/03/24 PHP
php中字符集转换iconv函数使用总结
2014/10/11 PHP
PHP实现的简单分页类及用法示例
2016/05/06 PHP
PHP中迭代器的简单实现及Yii框架中的迭代器实现方法示例
2020/04/26 PHP
让JavaScript拥有类似Lambda表达式编程能力的方法
2010/09/12 Javascript
js实现右下角可关闭最小化div(可用于展示推荐内容)
2013/06/24 Javascript
javascript控制层显示或隐藏的方法
2015/07/22 Javascript
总结Javascript中的隐式类型转换
2016/08/24 Javascript
js放到head中失效的原因与解决方法
2017/03/07 Javascript
vue实现条件判断动态绑定样式的方法
2018/09/29 Javascript
对angular 监控数据模型变化的事件方法$watch详解
2018/10/09 Javascript
Bootstrap 按钮样式与使用代码详解
2018/12/09 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
2020/03/03 Javascript
详解webpack的clean-webpack-plugin插件报错
2020/10/16 Javascript
Python编程中的异常处理教程
2015/08/21 Python
Python 类与元类的深度挖掘 I【经验】
2016/05/06 Python
如何利用Fabric自动化你的任务
2016/10/20 Python
python回调函数中使用多线程的方法
2017/12/25 Python
对python的文件内注释 help注释方法
2018/05/23 Python
如何通过50行Python代码获取公众号全部文章
2019/07/12 Python
Keras - GPU ID 和显存占用设定步骤
2020/06/22 Python
python删除文件、清空目录的实现方法
2020/09/23 Python
接口中的方法可以是abstract的吗
2015/07/23 面试题
SQL面试题
2013/12/09 面试题
一套英文Java笔试题面试题
2016/04/21 面试题
村级环境卫生整治方案
2014/05/04 职场文书
行政监察建议书
2014/05/19 职场文书
工地门卫岗位职责范本
2014/07/01 职场文书
公民授权委托书范本
2014/09/17 职场文书
导游词怎么写
2015/02/04 职场文书
会计出纳岗位职责
2015/03/31 职场文书
情侣之间的道歉短信
2015/05/12 职场文书
医院员工辞职信范文
2015/05/12 职场文书
民事调解书范文
2015/05/20 职场文书
小学一年级班主任工作经验交流材料
2015/11/02 职场文书
numpy array找出符合条件的数并赋值的示例代码
2022/06/01 Python