详解javascript中原始数据类型Null和Undefined


Posted in Javascript onDecember 17, 2015

当讨论JavaScript中的原始数据类型时,大多数人都知道的基本知识,从String,Number到Boolean。这些原始类型相当简单,行为符合常识。但是,本文将更多聚焦独特的原始数据类型Null和Undefined,是什么让他们如此相似,却又似是而非。

一、理解Null和Undefined
在JavaScript中,null是字面量同时也是语言中的关键字,用来表示无法识别的对象值。换句话说,这用来表示“无值(no value)”。虽然相似,undefined实际上代表了不存在的值(non-existence of a value)。都是完全不可变的,没有属性和方法,也不能给其属性赋值。事实上,试图访问或定义一个属性将会引发一个类型错误(TypeError)。正如他们的名字暗示的那样,他们是完全无效的值。

没有值代表的布尔值是false,这意味着他们在条件上下文中会被被计算为false,如if语句。使用相等操作符(= =)比较这两个值和其他false值,他们并不等于除了自己:

null == 0; // false
undefined == ""; // false
null == false; // false
undefined == false; // false
null == undefined; // true

尽管如此,和其他相似之处,但null和undefined并不是等价的。每个作为其独特的类型的唯一成员,undefined是Undefined类型和null是Null类型。使用全等操作符(===)比较这两个值,这要求类型和值都相等,下面证明这一点:

undefined === null; // false

这是一个重要的区别,服务于不同的目的和理由。区分这两个值,你可以认为undefined代表一个意想不到的没有值而null作为预期没有值的代表。
二、产生Undefined
有许多的方法产生一个undefined值的代码。它通常遇到当试图访问一个不存在的值时。在这种情况下,在JavaScript这种动态的弱类型语言中,只会默认返回一个undefined值,而不是上升为一个错误。
任何声明变量时没有提供一个初始值,都会有一个为undefined的默认值:

var foo; // 默认值为 undefined

当试图访问一个不存在的对象属性或数组项时,返回一个undefined值:

var array = [1, 2, 3];
var foo = array.foo; // foo 属性不存在, 返回 undefined
var item = array[5]; // 数组中没有索引为5的项,返回 undefined

如果省略了函数的返回语句,返回undefined:

var value = (function(){})(); // 返回 undefined

函数调用时未提供的值结果将为undefined参数值:

(function(undefined){
  // 参数是 undefined
})();

void操作符也可以返回一个undefined值。像Underscore的库使用它作为一个防御式的类型检查,因为它是不可变的,可以在任何上下文依赖返回undefined:

function isUndefined(obj){
  return obj === void 0;
}

最后,undefined是一个预定义的全局变量(不像null关键字)初始化为undefined值:

'undefined' in window; // true

ECMAScript 5中,这个变量是只读的,以前并非如此。

三、Null的用例
null的用例是使他与众不同的主要方面,因为不像undefined,null被认为是更有用。这正是为什么typeof操作符作用于null值时返回“object”。最初的理由是,现在仍然是,通常用作一个空引用一个空对象的预期,就像一个占位符。typeof的这种行为已经被确认为一个错误,虽然提出了修正,出于后兼容的目的,这一点已经保持不变。
这就是为什么JavaScript环境从来没有设置一个值为null;它必须以编程方式完成。正如文档MDN所说:
在api中,null是经常检索对象的地方可以预期,但没有相关的对象。
这适用于DOM,它是独立于语言的,不属于ECMAScript规范的范围。因为它是一个外部API,试图获取一个不存在的元素返回一个null值,而不是undefined。
一般来说,如果你需要给一个变量或属性指定一个不变值,将它传递给一个函数,或者从一个函数返回null,null几乎总是最好的选择。简而言之,JavaScript使用undefined并且程序员应该使用null。
null的另一个可行的用例,也被认为是良好的实践是一个显式指定变量为无效(object= null)当一个引用不再是必需的。通过分配null值,有效地清除引用,并假设对象没有引用其他代码,指定垃圾收集,确保回收内存。
四、深入挖掘
使null和undefined像黑洞的不只是他们的行为,而是在他们在JavaScript环境的内部的处理方式。他们似乎通常并不具有同样的关联特征与其他原生或内置对象。
在ES5中,Object.prototype.toString方法,已经成为实际的类型检查标准,这在null和undefined中被证明是一致的:

Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(undefined); // [object Undefined]

然而,Object.prototype.toString方法实际上并不是检索null的内部[[Class]]属性或undefined的公开构造函数。根据文档,以下步骤发生在被调用过程中:

如果值是undefined,返回“[object Undefined]”。

  • 如果这个值为null,则返回“[object Null]”。
  • 让O作为调用ToObject同时传递this值作为参数的结果值。
  • 让class是O的内部属性[[Class]]的值。
  • 返回的结果连接三个字符串“[object ”,class,和“]”的结果的字符串值。

该方法执行一个简单的字符串返回值,如果它检测到null或undefined和其他对象统一的功能。在整个规范中这是很常见的,因为当遇到null和undefined值时大多数方法包含一个简单的捕捉并返回。事实上,没有迹象表明他们包含与任何原生对象相关联的内部属性。就好像他们不是对象。我很想知道如果一个JavaScript的原生环境内部实际存在的显式方案会怎样?也许有人更熟悉一个可以参与的实现。

结论
无论这些原生对象多么不寻常,理解null和undefined之间的差异,和他们在JavaScript的语言基础中截然不同的角色。它可能不能使你的应用程序有所突破,但是一般来说,它仅被证明在开发和调试中长期有益。

以上就是针对javascript中原始数据类型Null和Undefined进行的介绍,希望对大家的学习有所帮助。

Javascript 相关文章推荐
Save a File Using a File Save Dialog Box
Jun 18 Javascript
innerhtml用法 innertext用法 以及innerHTML与innertext的区别
Oct 26 Javascript
javascript中bind函数的作用实例介绍
Sep 28 Javascript
jquery实现左右滑动菜单效果代码
Aug 27 Javascript
使用jquery实现鼠标滑过弹出更多相关信息层附源码下载
Nov 23 Javascript
关于session和cookie的简单理解
Jun 08 Javascript
BootStrapTable服务器分页实例解析
Dec 20 Javascript
Vue注册组件命名时不能用大写的原因浅析
Apr 25 Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 Javascript
Vue axios 将传递的json数据转为form data的例子
Oct 29 Javascript
jQuery 实现扁平式小清新导航
Jul 07 jQuery
js 图片懒加载的实现
Oct 21 Javascript
JS实现合并两个数组并去除重复项只留一个的方法
Dec 17 #Javascript
JS数组合并push与concat区别分析
Dec 17 #Javascript
理解Javascript的call、apply
Dec 16 #Javascript
javascript实现网站加入收藏功能
Dec 16 #Javascript
javascript实现无缝上下滚动特效
Dec 16 #Javascript
js实现将选中内容分享到新浪或腾讯微博
Dec 16 #Javascript
JavaScript运行过程中的“预编译阶段”和“执行阶段”
Dec 16 #Javascript
You might like
PHP基于MySQL数据库实现对象持久层的方法
2015/06/17 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
js function使用心得
2010/05/10 Javascript
Android中的jQuery:AQuery简介
2014/05/06 Javascript
让html页面不缓存js的实现方法
2014/10/31 Javascript
JavaScript实现更改网页背景与字体颜色的方法
2015/02/02 Javascript
JavaScript函数的调用以及参数传递
2015/10/21 Javascript
详解JavaScript逻辑And运算符
2015/12/04 Javascript
JS实现iframe自适应高度的方法(兼容IE与FireFox)
2016/06/24 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
2016/12/16 Javascript
JS如何生成一个不重复的ID的函数
2016/12/25 Javascript
JavaScript实现淘宝京东6位数字支付密码效果
2018/08/18 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
[13:25]VP vs VICI (BO3)
2018/06/07 DOTA
Python自然语言处理之词干,词形与最大匹配算法代码详解
2017/11/16 Python
Python实现的文本对比报告生成工具示例
2018/05/22 Python
Python函数参数匹配模型通用规则keyword-only参数详解
2019/06/10 Python
python,Django实现的淘宝客登录功能示例
2019/06/12 Python
python实现查找所有程序的安装信息
2020/02/18 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
Selenium之模拟登录铁路12306的示例代码
2020/07/31 Python
Python如何利用Har文件进行遍历指定字典替换提交的数据详解
2020/11/05 Python
Python3爬虫ChromeDriver的安装实例
2021/02/06 Python
如何用Python和JS实现的Web SSH工具
2021/02/23 Python
详解python的xlwings库读写excel操作总结
2021/02/26 Python
canvas实现图片马赛克的示例代码
2018/03/26 HTML / CSS
美国最值得信赖的宠物药房:Allivet
2019/03/23 全球购物
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
三年级语文教学反思
2014/02/01 职场文书
《称象》教学反思
2014/04/25 职场文书
2015年先进个人自荐书
2015/03/24 职场文书
2015年世界环境日活动方案
2015/05/05 职场文书
毕业典礼主持词
2015/06/29 职场文书
Python+Appium新手教程
2021/04/17 Python
SQL Server使用PIVOT与unPIVOT实现行列转换
2022/05/25 SQL Server
js前端面试常见浏览器缓存强缓存及协商缓存实例
2022/06/21 Javascript