当讨论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变量的原因!

系列文章导航:

1、你不知道的JavaScript–Item1 严格模式

2、你不知道的JavaScript–Item2 浮点数精度

3、你不知道的JavaScript–Item3 隐式强制转换

4、你不知道的JavaScript–Item4 基本类型和基本包装类型(引用类型)

5、你不知道的JavaScript–Item5 全局变量

6、你不知道的JavaScript–Item6 var预解析与函数声明提升(hoist )

7、你不知道的JavaScript–Item7 函数和(命名)函数表达式

8、你不知道的JavaScript–Item8 函数,方法,构造函数调用

9、你不知道的JavaScript–Item9 call(),apply(),bind()与回调

10、你不知道的JavaScript–Item10 闭包(closure)

11、你不知道的JavaScript–Item11 arguments对象

12、你不知道的JavaScript–Item12 undefined 与 null

13、你不知道的JavaScript–Item13 理解 prototype, getPrototypeOf 和_ proto_

14、你不知道的JavaScript–Item14 使用prototype的几点注意事项

15、你不知道的JavaScript–Item15 prototype原型和原型链详解

16、你不知道的JavaScript–Item16 for 循环和for…in 循环的那点事儿

17、你不知道的JavaScript–Item17 循环与prototype最后的几点小tips

18、你不知道的JavaScript–Item18 JScript的Bug与内存管理

19、你不知道的JavaScript–Item19 执行上下文(execution context)

20、你不知道的JavaScript–Item20 作用域与作用域链(scope chain)

21、你不知道的JavaScript–Item21 漂移的this


持续更新中……………….

版权声明:本文为小平果原创文章,转载请注明:http://blog.csdn.net/i10630226

你不知道的JavaScript--Item12 undefined 与 null的更多相关文章

  1. JavaScript中undefined与null的区别

    通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个undefined值.Javascript会自动将声明是没有进行初始化的变量设为undifined. 如果一个变量根本不存在会 ...

  2. javascript类型系统——undefined和null

    × 目录 [1]原因 [2]undefined [3]null 前面的话 一般的程序语言,表示空的只有null,但javascript的设计者Brendan Eich却设计了一个undefined,这 ...

  3. 【转】JavaScript中undefined与null的区别

    通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个undefined值.Javascript会自动将声明是没有进行初始化的变量设为undifined. 如果一个变量根本不存在会 ...

  4. Javascript数据类型——undefined和null的异同

    Javascript的基本数据类型中有undefined和null两种只有一个值得特殊数据类型.其中undefined表示未被初始化,不是为声明.而null表示一个空对象指针,而这也是使用typeof ...

  5. 【前端】javascript判断undefined、null、NaN;字符串包含等

    JS中判断null.undefined与NaN的方法 这篇文章主要介绍了JS中判断null.undefined与NaN的方法,需要的朋友可以参考下 . . 写了个 str ="s" ...

  6. 快速弄清JavaScript中undefined和null的区别

    ES6的7大数据类型里面有这俩玩意:undefined和null,让接触不深的学习者常常产生混淆,这俩玩意的区别在哪呢? 字面意思上来看,undefined是未(被我们)阐明的,未说明的,null则意 ...

  7. JavaScript的undefined与null、NaN的区别

    Javascript的数据类型 在JavaScript中,有三种住数据类型.两种复合数据类型和两种特殊数据类型. 1.主数据类型(基元数据类型) 字符串 String数据类型: 字符串值是一个由零个或 ...

  8. javascript 中 undefined 和 null 区别

    1.相同点 如果我们直接用 undefined == null  比较他们是相等的返回的将是 true. 2.区别 当我们用undefined === null 比较的时候最后返回的将是 false. ...

  9. JavaScript中Undefined 和 Null的区别

    Undefined 这个值表示变量不含有值. 可以通过将变量的值设置为 null 来清空变量. 例如: <script> var person; var car="Volvo&q ...

  10. javascript 数据类型 undefined 和null

    数据类型 undefind null boolean number string object type of 功能:检测变量类型 语法:type of 变量或 type of (变量) consol ...

随机推荐

  1. OpenCV——PS 图层混合算法 (二)

    具体的算法原理可以参考 PS图层混合算法之二(线性加深,线性减淡,变亮,变暗) // PS_Algorithm.h #ifndef PS_ALGORITHM_H_INCLUDED #define PS ...

  2. 关于UIView用户交互相关的属性和方法

    UIView除了负责展示内容给用户外还负责响应用户事件 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为NO则不响应用户事件,并且把当前控件从事件队列中删除 ...

  3. Mina源码阅读笔记(一)-整体解读

    今天的这一节,将从整体上对mina的源代码进行把握,网上已经有好多关于mina源码的阅读笔记,但好多都是列举了一下每个接口或者类的方法.我倒是想从mina源码的结构和功能上对这个框架进行剖析.源码的阅 ...

  4. LeetCode之旅(21)-Swap Nodes in Pairs

    题目: Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1-> ...

  5. Spring 学习笔记 Bean的作用域

    在配置文件中定义Bean时,用户不但可以配置Bean的属性值以及相互之间的依赖关系,还可以定义Bean的作用域.作用域将对Bean的生命周期和创建方式产生影响.在低版本的Spring中,仅有两个作用域 ...

  6. 存储引擎-Buffered tree

    Buffered-tree 也称为COLA,即cache-oblivious,可以不需要知道具体内存大小和一个块的大小,使用一套逻辑进行处理,因此内存大小可知,内存可能被临时占用去做其它事情. Buf ...

  7. C标准中关于空指针的那些事

    1 C标准不保证用所有二进制位都为0的变量来表示空指针,但它保证空指针与任何对象或函数的指针都不相等,取地址操作符&永远也不会返回空指针: 2 C标准称在指针上下文中的"值为0的整形 ...

  8. 数据准备<2>:数据质量检查-实战篇

    上一篇文章:<数据质量检查-理论篇>主要介绍了数据质量检查的基本思路与方法,本文作为补充,从Python实战角度,提供具体的实现方法. 承接上文,仍然从重复值检查.缺失值检查.数据倾斜问题 ...

  9. twisted高并发库transport函数处理数据包的些许问题

    还是在学校时间比较多, 能够把时间更多的花在学习上, 尽管工作对人的提升更大, 但是总是没什么时间学习, 而且工作的气氛总是很紧凑, 忙碌, 少了些许激情吧.适应就好了.延续着之前对twisted高并 ...

  10. 排序算法入门之冒泡排序及其优化(java实现)

    冒泡排序思想(从小到大): 比较相邻两个元素,如果第一个元素比第二个元素大,就交换他们的位置.第一趟,从第一个元素开始,第一个元素和第二个元素比较,如果第一个元素比第二个元素大,则交换位置:接下来比较 ...