Undefined 和 Null 是 Javascript 中两种特殊的原始数据类型(Primary Type),它们都只有一个值,分别对应 undefined 和 null ,这两种不同类型的值,既有着不同的语义和场景,又表现出较为相似的行为:

undefined

undefined 的字面意思就是:未定义的值 。这个值的语义是,希望表示一个变量最原始的状态,而非人为操作的结果 。 这种原始状态会在以下 4 种场景中出现:

【1】声明了一个变量,但没有赋值

var foo;
console.log(foo); // undefined

访问 foo,返回了 undefined,表示这个变量自从声明了以后,就从来没有使用过,也没有定义过任何有效的值,即处于一种原始而不可用的状态。

【2】访问对象上不存在的属性 

console.log(Object.foo); // undefined
var arr = [];
console.log([0]); // undefined

访问 Object 对象上的 foo 属性,返回 undefined , 表示Object 上不存在或者没有定义名为 foo 的属性。数组中的元素在内部也属于对象属性,访问下标就等于访问这个属性,返回 undefined ,就表示数组中不存在这个元素。

【3】函数定义了形参,但没有传递实参

//函数定义了形参 a
function fn(a) {
console.log(a); // undefined
}
fn(); //未传递实参

函数 fn 定义了形参 a, 但 fn 被调用时没有传递参数,因此,fn 运行时的参数 a 就是一个原始的、未被赋值的变量。

【4】使用 void 对表达式求值

void 0 ; // undefined
void false; // undefined
void []; // undefined
void null; // undefined
void function fn(){} ; // undefined

ECMAScript 明确规定 void 操作符 对任何表达式求值都返回 undefined ,这和函数执行操作后没有返回值的作用是一样的,JavaScript 中的函数都有返回值,当没有 return 操作时,就默认返回一个原始的状态值,这个值就是 undefined,表明函数的返回值未被定义。

因此,undefined 一般都来自于某个表达式最原始的状态值,不是人为操作的结果。当然,你也可以手动给一个变量赋值 undefined,但这样做没有意义,因为一个变量不赋值就是 undefined 。

null

null 的字面意思是:空值  。这个值的语义是,希望表示 一个对象被人为的重置为空对象,而非一个变量最原始的状态 。 在内存里的表示就是,栈中的变量没有指向堆中的内存对象,即:

当一个对象被赋值了null 以后,原来的对象在内存中就处于游离状态,GC 会择机回收该对象并释放内存。因此,如果需要释放某个对象,就将变量设置为 null,即表示该对象已经被清空,目前无效状态。试想一下,如果此处把 null 换成 undefined 会不会感到别扭? 显然语义不通,其操作不能正确的表达其想要的行为。

与 null 相关的另外一个问题需要解释一下:

typeof null == 'object'

null 有属于自己的类型 Null,而不属于Object类型,typeof 之所以会判定为 Object 类型,是因为JavaScript 数据类型在底层都是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,而 null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object 类型。

000 - 对象,数据是对象的应用

1 - 整型,数据是31位带符号整数

010 - 双精度类型,数据是双精度数字

100 - 字符串,数据是字符串

110 - 布尔类型,数据是布尔值

其实,我们可以通过另一种方法获取 null 的真实类型:

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

通过 Object 原型上的toString() 方法可以获取到JavaScript 中对象的真实数据类型,当然 undefined 类型也可以通过这种方式来获取:

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

相似性

虽然 undefined 和 null 的语义和场景不同,但总而言之,它们都表示的是一个无效的值。 因此,在JS中对这类值访问属性时,都会得到异常的结果:

null.toString(); // Cannot read property 'toString' of null
undefined.toString(); // Cannot read property 'toString' of undefined  

ECMAScript 规范认为,既然 null 和  undefined 的行为很相似,并且都表示 一个无效的值,那么它们所表示的内容也具有相似性,即有

undefined == null; // true

不要试图通过转换数据类型来解释这个结论,因为:

Number(null); // 0
Number(undefined); // NaN // 在比较相等性之前,null 没有被转换为其他类型
null == 0 ; //false

但 === 会返回 false ,因为全等操作 === 在比较相等性的时候,不会主动转换分项的数据类型,而两者又不属于同一种类型:

undefined === null; // false,类型不相同
undefined !== null; // true, 类型不相同

总结

用一句话总结两者的区别就是:undefined 表示一个变量自然的、最原始的状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。所以,在实际使用过程中,为了保证变量所代表的语义,不要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。

原创发布 @一像素 2017.08

对 Undefined 与 Null 的一些理解的更多相关文章

  1. 来理解undefined 和 null 区别

    之前虽然也知道这两个之间的区别,但是让我描述的话,感觉上还是说的不是很清楚.今天也详细看了一次这个知识点,现在来说说这两者间的区别. null: Null类型,代表“空值”,代表一个空对象指针,使用t ...

  2. 理解Javascript__理解undefined和null

    来自普遍的回答: 其实在 ECMAScript 的原始类型中,是有Undefined 和 Null 类型的. 这两种类型都分别对应了属于自己的唯一专用值,即undefined 和 null. 值 un ...

  3. 怎样理解undefined和 null

    前言: undefined表示 "未定义", null 表示 "空" 第一步: 一般在变量或属性没有声明或者声明以后没有赋值时, 这个变量的值就是undefin ...

  4. 你不知道的JavaScript--Item12 undefined 与 null

    当讨论JavaScript中的原始数据类型时,大多数人都知道从String.Number到Boolean的基本知识.这些原始类型相当简单,行为符合常识.但是,本文将更多关注独特的原始数据类型Null和 ...

  5. 【转】javascript中not defined、undefined、null以及NaN的区别

    原文链接(点击跳转) 第一:not defined 演示代码:   <span style="font-size:12px;"><span style=" ...

  6. 【学习笔记】js中undefined和null的区别和联系

    在JavaScript中存在这样两种原始类型:Null与Undefined.这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是Undefined? Undef ...

  7. javascript中typeof、undefined 和 null

    typeof 是运算符,注意不是函数,是运算符,其作用,是考察变量究竟是什么类型.或曰,是变量是否定义或是否初始化的照妖镜.返回值是字符串. undefined 表示一个对象没有被定义或者没有被初始化 ...

  8. JavaScript:undefined And null差异

    班吃饭的时候,同事偶然问了一个问题:undefined和null究竟有什么差别?无法回答,回去查阅相关文档,算了有了一个了解,做相关的总结.在開始之前,请看例如以下代码,算是抛出这个问题: conso ...

  9. JavaScript中undefined与null的区别

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

随机推荐

  1. Java公开课-05.log4j

    log4j 一,log4j简介 1.如果程序中出现异常,我们怎么解决? 01.使用异常处理机制===>异常 (但是使用原则是,能不用异常处理机制,最好不用,怎么办?) 02.通过debug调试 ...

  2. 在webpack里使用jquery.mCustomScrollbar插件

    malihu-custom-scrollbar-plugin是一个依赖jquery的自定义网页滚动条样式插件 网站:http://manos.malihu.gr/jquery-custom-conte ...

  3. 【gcd+stl】UVa1642 Magical GCD

    Description 一个长度为n的数列,选一个连续子序列,使得子序列的公约数*长度最大,求这个最大值.n<=1e5. Solution 连续子序列一般都要用滑动窗口是吧(固定r,快速计算最优 ...

  4. 【prufer编码】BZOJ1211 [HNOI2004]树的计数

    Description 给定一棵树每个节点度的限制为di,求有多少符合限制不同的树. Solution 发现prufer码和度数必然的联系 prufer码一个点出现次数为它的度数-1 我们依然可以把树 ...

  5. BZOJ_2440_[中山市选2011]完全平方数_容斥原理+线性筛

    BZOJ_2440_[中山市选2011]完全平方数_容斥原理 题意: 求第k个不是完全平方数倍数的数 分析: 二分答案,转化成1~x中不是完全平方数倍数的数的个数 答案=所有数-1个质数的平方的倍数+ ...

  6. BZOJ_2734_[HNOI2012]集合选数_构造+状压DP

    BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...

  7. Spring事务(一) Markdown 版

    事务 事务的特性(ACID) 原子性(Atomicity) 原子性要求事务所包含的全部操作是一个不可分割的整体,这些操作要么全部提交成功,要么只要其中一个操作失败,就全部"成仁" ...

  8. Github泄露扫描系统

    Github leaked patrol Github leaked patrol为一款github泄露巡航工具: 提供了WEB管理端,后台数据库支持SQLITE3.MYSQL和POSTGRES 双引 ...

  9. XSS过滤JAVA过滤器filter 防止常见SQL注入

    Java项目中XSS过滤器的使用方法. 简单介绍: XSS : 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩 ...

  10. C# WinForm ShowInTaskbar Api Version

    using System; using System.Runtime.InteropServices; namespace x { unsafe class NativeWindow { /* * W ...