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 相关文章推荐
JavaScript 轻松搞定快捷留言功能 只需一行代码
Apr 01 Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
Dec 27 Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
May 08 Javascript
用javascript判断IE版本号简单实用且向后兼容
Sep 11 Javascript
js实现滚动条滚动到某个位置便自动定位某个tr
Jan 20 Javascript
js正则表达式最长匹配(贪婪匹配)和最短匹配(懒惰匹配)用法分析
Dec 27 Javascript
AngularJS报错$apply already in progress的解决方法分析
Jan 30 Javascript
React-Router如何进行页面权限管理的方法
Dec 06 Javascript
vue实现样式之间的切换及vue动态样式的实现方法
Dec 19 Javascript
vue2.0 可折叠列表 v-for循环展示的实例
Sep 07 Javascript
VUE前后端学习tab写法实例
Aug 06 Javascript
在layui.use 中自定义 function 的正确方法
Sep 16 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
解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法
2007/03/29 PHP
简单的php缓存类分享     php缓存机制
2014/01/22 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
php检测图片主要颜色的方法
2015/07/01 PHP
PHP序列化操作方法分析
2016/09/28 PHP
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
js转化毫秒为时间格式代码
2014/04/10 Javascript
jquery处理json数据实例分析
2014/06/03 Javascript
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
纯JS代码实现气泡效果
2016/05/04 Javascript
JavaScript中的事件委托及好处
2016/07/12 Javascript
JS获得多个同name 的input输入框的值的实现方法
2017/01/09 Javascript
微信小程序商城项目之商品属性分类(4)
2017/04/17 Javascript
dropload.js插件下拉刷新和上拉加载使用详解
2017/10/20 Javascript
jquery实现搜索框功能实例详解
2018/07/23 jQuery
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
VUE+node(express)实现前后端分离
2019/10/13 Javascript
基于jQuery实现挂号平台首页源码
2020/01/06 jQuery
三步搞定:Vue.js调用Android原生操作
2020/09/07 Javascript
python爬取个性签名的方法
2018/06/17 Python
对python 生成拼接xml报文的示例详解
2018/12/28 Python
Python XML转Json之XML2Dict的使用方法
2019/01/15 Python
python3.x实现base64加密和解密
2019/03/28 Python
pandas.DataFrame.drop_duplicates 用法介绍
2020/07/06 Python
Python3爬虫里关于Splash负载均衡配置详解
2020/07/10 Python
python读取excel进行遍历/xlrd模块操作
2020/07/12 Python
CSS3中Transform动画属性用法详解
2016/07/04 HTML / CSS
美国销售第一的智能手机和平板电脑保护壳:OtterBox
2017/12/21 全球购物
英国儿童鞋和靴子:Start-Rite
2019/05/06 全球购物
定义一结构体变量,用其表示点坐标,并输入两点坐标,求两点之间的距离
2015/08/17 面试题
大学毕业生通用求职信
2013/09/28 职场文书
个人课题方案
2014/05/08 职场文书
校园新闻广播稿5篇
2014/10/10 职场文书
学校拾金不昧表扬信
2015/01/16 职场文书
班主任远程培训研修日志
2015/11/13 职场文书
《红领巾真好》教学反思
2016/02/16 职场文书