javascript中undefined与null的区别


Posted in Javascript onAugust 16, 2015

大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的None,Ruby语言的nil。

有点奇怪的是,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里一样,被当成一个对象。但是,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

下面做个小小的总结

null是JavaScript关键字,表示非对象。

undefined表示没有值,说明这个值不存在或是没有初始化。

相同点 不同点
自有类型唯一值 null是对象,undefined是保留字
没有属性和方法 null在参与数学运算中转化成0,undefined在数学运算中无法转化或是转化成NaN
==认为相等,===认为不等 null !==undefined //true
都是假值,在布尔值变量表示值相同 null是空对象,undefined是window的属性(但是不是对象属性)
  alert(typeof null) // object ; alert(typeof undefined) // undefined ;
Javascript 相关文章推荐
CSS+JS构建的图片查看器
Jul 22 Javascript
js 数组实现一个类似ruby的迭代器
Oct 27 Javascript
jQuery中:eq()选择器用法实例
Dec 29 Javascript
JS+CSS实现淡入式焦点图片幻灯切换效果的方法
Feb 26 Javascript
jQuery下拉美化搜索表单效果代码分享
Aug 25 Javascript
基于JavaScript实现类似于百度学术高级检索功能
Mar 02 Javascript
JQuery实现文字无缝滚动效果示例代码(Marquee插件)
Mar 07 Javascript
微信小程序 获取二维码实例详解
Jun 23 Javascript
微信小程序实现顶部下拉菜单栏
Nov 04 Javascript
Vue 事件处理操作实例详解
Mar 05 Javascript
新手快速入门JavaScript装饰者模式与AOP
Jun 24 Javascript
Node.js中的异步生成器与异步迭代详解
Jan 31 Javascript
swtich/if...else的替代语句
Aug 16 #Javascript
javascript数组去重的六种方法汇总
Aug 16 #Javascript
JS+CSS实现下拉列表框美化效果(3款)
Aug 15 #Javascript
js时钟翻牌效果实现代码分享
Jul 31 #Javascript
js实现点击文本框显示日期选择器特效代码分享
May 21 #Javascript
jQuery树形下拉菜单特效代码分享
Aug 15 #Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
Aug 15 #Javascript
You might like
打造超酷的PHP数据饼图效果实现代码
2011/11/23 PHP
PHP的引用详解
2015/02/22 PHP
详解CSS样式中的 !important * _ 符号
2021/03/09 HTML / CSS
javascript编程起步(第二课)
2007/01/10 Javascript
js利用div背景,做一个竖线的效果。
2008/11/22 Javascript
js单例模式详解实例
2013/11/21 Javascript
node.js中使用node-schedule实现定时任务实例
2014/06/03 Javascript
javascript实现根据3原色制作颜色选择器的方法
2015/07/17 Javascript
js从外部获取图片的实现方法
2016/08/05 Javascript
JavaScript中省略元素对数组长度的影响
2016/10/26 Javascript
使用Bootstrap Tabs选项卡Ajax加载数据实现
2016/12/23 Javascript
nodejs中使用HTTP分块响应和定时器示例代码
2017/03/19 NodeJs
解决Jstree 选中父节点时被禁用的子节点也会选中的问题
2017/12/27 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
2019/04/30 Javascript
浅谈目前可以使用ES10的5个新特性
2019/06/25 Javascript
Vue3 中的数据侦测的实现
2019/10/09 Javascript
vue使用swiper实现中间大两边小的轮播图效果
2019/11/24 Javascript
JavaScript函数重载操作实例浅析
2020/05/02 Javascript
[01:18]DOTA2超级联赛专访hanci ForLove淘汰感言曝光
2013/06/04 DOTA
[49:31]TFT vs Mski Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
Python编程中time模块的一些关键用法解析
2016/01/19 Python
Python使用中文正则表达式匹配指定中文字符串的方法示例
2017/01/20 Python
python实现简单日期工具类
2019/04/24 Python
python中时间模块的基本使用教程
2019/05/14 Python
基于Django框架的权限组件rbac实例讲解
2019/08/31 Python
详解python opencv、scikit-image和PIL图像处理库比较
2019/12/26 Python
浅析Python 简单工厂模式和工厂方法模式的优缺点
2020/07/13 Python
俄罗斯游戏商店:Buka
2020/03/01 全球购物
合作经营协议书范本
2014/09/16 职场文书
2014年煤矿工人工作总结
2014/12/08 职场文书
新郎新娘答谢词
2015/01/04 职场文书
小兵张嘎观后感
2015/06/03 职场文书
Redis模仿手机验证码发送的实现示例
2021/11/02 Redis
Mysql Innodb存储引擎之索引与算法
2022/02/15 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
2022/07/15 MySQL