跟我学习javascript的undefined与null


Posted in Javascript onNovember 17, 2015

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

一、理解null和undefined

在JavaScript中,null是字面量同时也是语言中的关键字,用来表示无法识别的对象值。换句话说,这用来表示“无值(no value)”,但你可以决定什么时候得到期望值。

虽然相似,undefined实际上代表了不存在的值(non-existence of a value),也即你有东西丢失了。两者都是完全不可变的,没有属性和方法,也不能给其属性赋值。事实上, 当你试图访问或定义null 与 undefined的一个属性将会引发一个类型错误(TypeError)。

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

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

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

null === undefined; //false
typeof null; //"object"
typeof undefined; //"undefined"

上面说明:null 这是一个对象,但是为空。而且 null 是 JavaScript 保留关键字。
另外null 参与数值运算时其值会自动转换为 0 ,因此,下列表达式计算后会得到正确的数值:

123 + null; //123 
123 * null;
 //0

undefined是全局对象(window)的一个特殊属性,其值是未定义的。但 typeof undefined 返回 ‘undefined' 。
虽然undefined是有特殊含义的,但它确实是一个属性,而且是全局对象(window)的属性。请看下面的代码:

alert('undefined' in window);//输出:true 
var anObj = {}; 
alert('undefined' in anObj); //输出:false

从中可以看出,undefined是window对象的一个属性,但却不是anObj对象的一个属性。
注意:

  • 尽管undefined是有特殊含义的属性,但却不是JavaScript的保留关键字。 undefined参与任何数值计算时,其结果一定是NaN。 随便说一下,NaN是全局对象(window)的另一个特殊属性,Infinity也是。这些特殊属性都不是JavaScript的保留关键字!
  • 验证一个值或者一个对象为null时,需要用“===” 来判定,若只用“==”,则无法判定是null 还是 undefined.

二、产生Undefined情况
有许多的方法产生一个undefined值的代码。它通常遇到当试图访问一个不存在的值时。在这种情况下,在JavaScript这种动态的弱类型语言中,只会默认返回一个undefined值,而不是上升为一个错误。

1、任何声明变量时没有提供一个初始值,都会有一个为undefined的默认值:

var foo; // 默认值为 undefined

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

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

3、如果省略了函数的返回语句, 或者return语句未带任何参数返回undefined:

var value = (function(){

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

4、调用函数时,应该提供的参数没有提供,该参数等于undefined

function f(x){
  console.log(x)
}
f(); // undefined

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

'undefined' in window; // true

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

三、null的用例

null的用例是使他与众不同的主要方面,因为不像undefined,null被认为是更有用。这正是为什么typeof操作符作用于null值 时返回“object”。最初的理由是,现在仍然是,通常用作一个空引用一个空对象的预期,就像一个占位符。typeof的这种行为已经被确认为一个错 误,虽然提出了修正,出于后兼容的目的,这一点已经保持不变。

一般来说,如果你需要给一个变量或属性指定一个不变值,将它传递给一个函数,或者从一个函数返回null,null几乎总是最好的选择。简而言之,JavaScript使用undefined并且程序员应该使用null。

null的另一个可行的用例,也被认为是良好的实践是一个显式指定变量为无效(object= null)当一个引用不再是必需的。通过分配null值,有效地清除引用,并假设对象没有引用其他代码,指定垃圾收集,确保回收内存。

四、提高undefined性能

当我们在程序中使用undefined值时,实际上使用的是window对象的undefined属性。 同样,当我们定义一个变量但未赋予其初始值,例如:

var aValue;

这时,JavaScript在所谓的预编译时会将其初始值设置为对window.undefined属性的引用, 于是,当我们将一个变量或值与undefined比较时,实际上是与window对象的undefined属性比较。这个比较过程中,JavaScript会搜索window对象名叫‘undefined'的属性,然后再比较两个操作数的引用指针是否相同。

由于window对象的属性值是非常多的,在每一次与undefined的比较中,搜索window对象的undefined属性都会花费时 间。在需要频繁与undefined进行比较的函数中,这可能会是一个性能问题点。因此,在这种情况下,我们可以自行定义一个局部的undefined变 量,来加快对undefined的比较速度。例如:

function anyFunc() { 
  var undefined; 
  //自定义局部undefined变量 
  if(x == undefined) 
  //作用域上的引用比较 
  while(y != undefined) 
  //作用域上的引用比较 
};

其中,定义undefined局部变量时,其初始值会是对window.undefined属性值的引用。新定义的局部undefined变 量存在与该函数的作用域上。在随后的比较操作中,JavaScript代码的书写方式没有任何的改变,但比较速度却很快。因为作用域上的变量数量会远远少 于window对象的属性,搜索变量的速度会极大提高。

这就是许多前端JS框架为什么常常要自己定义一个局部undefined变量的原因!

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
Jquery 弹出层插件实现代码
Oct 24 Javascript
超级酷和最实用的jQuery实例收集(20个)
Apr 21 Javascript
js定义对象或数组直接量时各浏览器对多余逗号的处理(json)
Mar 05 Javascript
JavaScript事件委托技术实例分析
Feb 06 Javascript
js面向对象的写法
Feb 19 Javascript
详解webpack介绍&安装&常用命令
Jun 29 Javascript
JS路由跳转的简单实现代码
Sep 21 Javascript
vue-cli3.0 特性解读
Apr 22 Javascript
详解es6超好用的语法糖Decorator
Aug 01 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
Sep 13 Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
Apr 17 Javascript
JS中队列和双端队列实现及应用详解
Sep 29 Javascript
跟我学习javascript的arguments对象
Nov 16 #Javascript
JavaScript函数学习总结以及相关的编程习惯指南
Nov 16 #Javascript
js实现获取div坐标的方法
Nov 16 #Javascript
跟我学习javascript的闭包
Nov 16 #Javascript
jQuery链式操作实例分析
Nov 16 #Javascript
javascript伸缩型菜单实现代码
Nov 16 #Javascript
基于jQuery实现的仿百度首页滑动选项卡效果代码
Nov 16 #Javascript
You might like
解析wamp5下虚拟机配置文档
2013/06/27 PHP
php经典算法集锦
2015/11/14 PHP
Ajax实现对静态页面的文章访问统计功能示例
2016/10/10 PHP
laravel 数据迁移与 Eloquent ORM的实现方法
2019/04/12 PHP
PDO实现学生管理系统
2020/03/21 PHP
JS创建优美的页面滑动块效果 - Glider.js
2007/09/27 Javascript
Javascript 通过json自动生成Dom的代码
2010/04/01 Javascript
页面只能打开一次Cooike如何实现
2012/12/04 Javascript
node.js中的fs.link方法使用说明
2014/12/15 Javascript
轻松创建nodejs服务器(10):处理POST请求
2014/12/18 NodeJs
移动端js触摸事件详解
2016/09/18 Javascript
如何使用headjs来管理和异步加载js
2016/11/29 Javascript
JavaScript中动态向表格添加数据
2017/01/24 Javascript
js实现显示手机号码效果
2017/03/09 Javascript
JS模拟超市简易收银台小程序代码解析
2017/08/18 Javascript
浅谈vuejs实现数据驱动视图原理
2018/02/23 Javascript
对Vue.js之事件的绑定(v-on: 或者 @ )详解
2018/09/15 Javascript
细说Vue组件的服务器端渲染的过程
2019/05/30 Javascript
在vue中使用image-webpack-loader实例
2020/11/12 Javascript
[02:52]DOTA2新手基础教程 米波
2014/01/21 DOTA
Python编程实现二叉树及七种遍历方法详解
2017/06/02 Python
python编程线性回归代码示例
2017/12/07 Python
python实现隐马尔科夫模型HMM
2018/03/25 Python
Python实现string字符串连接的方法总结【8种方式】
2018/07/06 Python
Python常见内置高效率函数用法示例
2018/07/31 Python
python中协程实现TCP连接的实例分析
2018/10/14 Python
python pygame实现五子棋小游戏
2020/10/26 Python
解决Python import docx出错DLL load failed的问题
2020/02/13 Python
Jupyter 无法下载文件夹如何实现曲线救国
2020/04/22 Python
django rest framework 过滤时间操作
2020/07/12 Python
Css3+Js制作漂亮时钟(附源码)
2013/04/24 HTML / CSS
汽车机电维修工求职信
2014/09/30 职场文书
教师思想工作总结2015
2015/05/13 职场文书
考试后的感想
2015/08/07 职场文书
Python连接Postgres/Mysql/Mongo数据库基本操作大全
2021/06/29 Python
JS高级程序设计之class继承重点详解
2022/07/07 Javascript