详解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 相关文章推荐
Dreamweaver jQuery智能提示插件,支持版本提示,支持1.6api
Jul 31 Javascript
jquery插件制作 自增长输入框实现代码
Aug 17 jQuery
window resize和scroll事件的基本优化思路
Apr 29 Javascript
JavaScript Sort 的一个错误用法示例
Mar 20 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖动基本操作
Nov 30 Javascript
jQuery绑定事件的几种实现方式
May 09 Javascript
javascript使用闭包模拟对象的私有属性和方法
Oct 05 Javascript
js基本算法:冒泡排序,二分查找的简单实例
Oct 08 Javascript
jQuery监听文件上传实现进度条效果的方法
Oct 16 Javascript
Node.js的特点详解
Feb 03 Javascript
angularjs点击图片放大实现上传图片预览
Feb 24 Javascript
简单介绍react redux的中间件的使用
Apr 06 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
mysql5写入和读出乱码解决
2006/11/25 PHP
PHP表单数据写入MySQL数据库的代码
2016/05/31 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
PHP反射机制原理与用法详解
2017/02/15 PHP
thinkPHP5 tablib标签库自定义方法详解
2017/05/10 PHP
PHP使用CURL实现下载文件功能示例
2019/06/03 PHP
什么是json和jsonp,jQuery json实例详详细说明
2012/12/11 Javascript
JavaScript编程的10个实用小技巧
2014/04/18 Javascript
ExtJS4 动态生成的grid导出为excel示例
2014/05/02 Javascript
javascript中使用new与不使用实例化对象的区别
2015/06/22 Javascript
JavaScript实现的多个图片广告交替显示效果代码
2015/09/04 Javascript
基于jQuery实现鼠标点击导航菜单水波动画效果附源码下载
2016/01/06 Javascript
Bootstrap风格的WPF样式
2016/12/07 Javascript
jQuery中值得注意的trigger方法浅析
2016/12/12 Javascript
JavaScript面向对象精要(上部)
2017/09/12 Javascript
vue.js实现插入数值与表达式的方法分析
2018/07/06 Javascript
微信小程序本地存储实现每日签到、连续签到功能
2019/10/09 Javascript
如何在Node和浏览器控制台中打印彩色文字
2020/01/09 Javascript
python自然语言编码转换模块codecs介绍
2015/04/08 Python
Tensorflow卷积神经网络实例
2018/05/24 Python
Flask框架web开发之零基础入门
2018/12/10 Python
为什么从Python 3.6开始字典有序并效率更高
2019/07/15 Python
基于MATLAB和Python实现MFCC特征参数提取
2019/08/13 Python
Python从文件中读取指定的行以及在文件指定位置写入
2019/09/06 Python
解决Python中回文数和质数的问题
2019/11/24 Python
python模拟斗地主发牌
2020/04/22 Python
基于python获取本地时间并转换时间戳和日期格式
2020/10/27 Python
浅析python字符串前加r、f、u、l 的区别
2021/01/24 Python
用python 绘制茎叶图和复合饼图
2021/02/26 Python
深入研究HTML5实现图片压缩上传功能
2016/03/25 HTML / CSS
eVitamins日本:在线购买折扣维生素、补品和草药
2019/04/04 全球购物
注塑工厂厂长岗位职责
2013/12/02 职场文书
党校学习心得体会范文
2014/09/09 职场文书
2014年最新学校运动会广播稿
2014/09/17 职场文书
学雷锋广播稿大全
2015/08/19 职场文书
导游词之重庆渣滓洞
2020/01/08 职场文书