详解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 相关文章推荐
基于mouseout和mouseover等类似事件的冒泡问题解决方法
Nov 18 Javascript
javascript的push使用指南
Dec 05 Javascript
浅谈类似于(function(){}).call()的js语句
Mar 30 Javascript
JavaScript 面向对象与原型
Apr 10 Javascript
JS获取月份最后天数、最大天数与某日周数的方法
Dec 08 Javascript
js 定位到某个锚点的方法
Nov 19 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
Jan 11 Javascript
浅谈VUE监听窗口变化事件的问题
Feb 24 Javascript
JS高级技巧(简洁版)
Jul 29 Javascript
vue项目中跳转到外部链接的实例讲解
Sep 20 Javascript
easyUI使用分页过滤器对数据进行分页操作实例分析
Jun 01 Javascript
vue 项目软键盘回车触发搜索事件
Sep 09 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
ECMall支持SSL连接邮件服务器的配置方法详解
2014/05/19 PHP
在SAE上搭建最新wordpress的方法
2014/12/21 PHP
php文件上传简单实现方法
2015/01/24 PHP
PHP连接MySQL数据的操作要点
2015/03/20 PHP
PHP发送短信代码分享
2015/08/11 PHP
Yii2框架引用bootstrap中日期插件yii2-date-picker的方法
2016/01/09 PHP
详解cookie验证的php应用的一种SSO解决办法
2017/10/20 PHP
JSON PHP中,Json字符串反序列化成对象/数组的方法
2018/05/31 PHP
Extjs学习笔记之一 初识Extjs之MessageBox
2010/01/07 Javascript
Javascript的数组与字典用法与遍历对象的属性技巧
2012/11/07 Javascript
javascript检查某个元素在数组中的索引值
2016/03/30 Javascript
BootStrap入门教程(三)之响应式原理
2016/09/19 Javascript
JQuery中Ajax的操作完整例子
2017/03/07 Javascript
深入理解vue路由的使用
2017/03/24 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
2018/01/08 Javascript
angular基于ng-alain定义自己的select组件示例
2018/02/23 Javascript
详解angular应用容器化部署
2018/08/14 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
[01:11:21]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第一场 3月6日
2021/03/11 DOTA
Python的条件语句与运算符优先级详解
2015/10/13 Python
Tensorflow进行多维矩阵的拆分与拼接实例
2020/02/07 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
2020/06/15 Python
Python自动化xpath实现自动抢票抢货
2020/09/19 Python
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
德国最大的婴儿用品网上商店:Kidsroom.de(支持中文)
2020/09/02 全球购物
工业设计毕业生自荐信
2014/04/13 职场文书
乳制品整治工作方案
2014/05/29 职场文书
2014乡镇班子个人对照检查材料思想汇报
2014/09/26 职场文书
教师党员个人总结
2015/02/10 职场文书
2015年信息中心工作总结
2015/05/25 职场文书
跳高加油稿
2015/07/21 职场文书
创业计划书之面包店
2019/09/17 职场文书
一篇文章告诉你如何实现Vue前端分页和后端分页
2022/02/18 Vue.js
JAVA SpringMVC实现自定义拦截器
2022/03/16 Python
分析SQL窗口函数之取值窗口函数
2022/04/21 Oracle
TaiShan 200服务器安装Ubuntu 18.04的图文教程
2022/06/28 Servers