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. python中读写excel并存入mysql

    为了一个突如其来的想法:用python简单解决就好.现在算是把这个项目需要的基础功能坑都填完了.剩下就是AI和数据展示方面的坑了. 今天遇到的坑是: 1.从excel读出的中文是乱码 2.中文写入my ...

  2. c#Socket客户端和服务端的信息发送

    这是我制作的界面信息,c# Socket通信的简单使用,刚开始学习,不对的地方请大家指教,目前是可以运行的,之后自己在慢慢添加新的东西.同时了解Tcp协议的三次握手.希望对跟我一样的初学者有所帮助. ...

  3. SpringBoot操作数据库 2017.12.14

    http://blog.csdn.net/forezp/article/details/61472783

  4. JavaScript单线程和异步机制

    随着对JavaScript学习的深入和实践经验的积累,一些原理和底层的东西也开始逐渐了解.早先也看过一些关于js单线程和事件循环的文章,不过当时看的似懂非懂,只留了一个大概的印象:浏览器中的js程序时 ...

  5. 你不知道的JavaScript--Item28 垃圾回收机制与内存管理

    1.垃圾回收机制-GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性 ...

  6. dom操作相关,byebye T T

    o = { name: 'aa', price: 11, } function add(items) { var bodys = document.getElementsByTagName('tbod ...

  7. 你不知道的JavaScript--Item11 arguments对象

    1.什么是arguments arguments 是是JavaScript里的一个内置对象,它很古怪,也经常被人所忽视,但实际上是很重要的.所有主要的js函数库都利用了arguments对象.所以ag ...

  8. jQuery中 $.ajax()方法详解

    $.ajax()方法详解 jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Strin ...

  9. 12.app后端如何选择合适的数据库产品

    app后端的开发中,经常要面临的一个问题是:数据放在哪里? mysql ?redis?mongodb? 现在有这么多优秀的开源数据库产品,怎么根据业务场景来选择合适的数据? 常用的数据库产品的优缺点又 ...

  10. python爬取所有微信好友的信息

    ''' 爬取所有T信好友的信息 ''' import itchat from pandas import DataFrame itchat.login() friends=itchat.get_fri ...