转载自:

作者:一像素

www.cnblogs.com/onepixel/p/7337248.html

最近在看《JavaScript高级程序设计》一书,书中讲到相等操作符(==)时说,要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,但要记住 null == undefined 会返回 true 。的确,在ECMAScript规范中也是这样定义的,但我认为这样来理解这件事情,似乎有些浮于表面,网上也有很多关于这个问题的文章,下面我希望从一个全新的角度来分析 null 和 undefined 的区别,从而理解两者为何会相等:

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

1、undefined

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

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

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

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

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

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

访问Object对象上的 foo 属性,同样也返回 undefined , 表示Object 上不存在或者没有定义名为 “foo” 的属性。

【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 。

2、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]


3、相似性

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

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

undefined == null; //true

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

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

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

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


4、总结

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

null == undefined ?相关推荐

  1. Javascript中的0,false,null,undefined,空字符串对比

    先看一段代码: <script type="text/javascript">alert(typeof (false) === "boolean") ...

  2. js中null,undefined,false,0,'',[],{}判断方法

    目录 1.数据类型 2.JSON字符串 3.数字类型 4.非的布尔值 5.与非比较 一.单独判断 1.null 2.undefined 3.0 4."" 5.判断undefined ...

  3. js 中null,undefined区别

    首先摘自阮一峰先生的文章: 大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的None,Ruby语言的nil. 有点奇 ...

  4. js 判断 ““,null,undefined

    js 判断 "",null,undefined if (mid == "" || mid == null || mid == undefined) { // & ...

  5. JavaScript终极面试题:null == undefined、[]+{}、{}+{}等结果多少呢?看完遍打通了奇经八脉任何对象的运算都会了

    JavaScript终极面试题:null == undefined.[]+{}.{}+{}等结果多少呢?看完遍打通了奇经八脉任何对象的运算都会了 一.等于的原理 二.区别 三.实例(附带各种运算符解析 ...

  6. 在js中if条件为null/undefined/0/NaN/表达式时,统统被解释为false,此外均为true

    Boolean 表达式 一个值为 true 或者 false 的表达式.如果需要,非 Boolean 表达式也可以被转换为 Boolean 值,但是要遵循下列规则: 所有的对象都被当作 true. 当 ...

  7. js中使用0 “” null undefined {}需要注意

    注意:在js中0为空(false) ,代表空的还有"",null ,undefined: 如果做判断if(!上面的四种值):返回均为false console.log(!null) ...

  8. null == undefined

    分析 null 和 undefined 的区别,从而理解两者为何会相等

  9. 解剖JavaScript中的null和undefined

    在JavaScript开发中,被人问到:null与undefined到底有啥区别? 一时间不好回答,特别是undefined,因为这涉及到undefined的实现原理.于是,细想之后,写下本文,请各位 ...

最新文章

  1. 商务网站开发这些优势值得青睐
  2. 012_CSS相邻兄弟选择器
  3. Android -- Fragment动画异常Unknown animation name: objectAnimator
  4. C++ 标准库类型 string
  5. Asp.net中实现同一用户名同时登陆,注销先前用户(转)
  6. Linux学习笔记(五)
  7. POJ1003/1004/1005/1207/3299/2159/1083/3094/2388解题(刷一波水题)
  8. django 1.8 官方文档翻译: 1-2-3 编写你的第一个Django应用,第3部分
  9. dp---数字三角形问题
  10. 异步 HttpContext.Current 为空null 另一种解决方法
  11. 在c#使用Windows IOCP(完成端口)编程研究
  12. 从web层运作流程认识Struts2
  13. linux虚拟机scsi类型,linux虚拟机的scsi设备id与盘符不一致问题的解决
  14. python 高斯滤波
  15. 笛卡尔心形函数表达式_笛卡尔爱心函数表达式 笛卡尔形式
  16. netty做一个posp的网络_Java网络通信基础系列-Netty实现HTTP服务
  17. python小球弹弹弹_python3.6使用tkinter实现弹跳小球游戏
  18. keras有cpu和gpu版本的区别
  19. 【毕业设计之PHP系列】PHP课程网站络管理系统
  20. 如何用计算机放音乐,教你如何用iPhone远程遥控电脑播放音乐教程

热门文章

  1. Python3 抓取网页小说
  2. 采购申请审批策略增强
  3. VulnHub DC1靶机渗透测试
  4. BIOS基础知识(下)
  5. DiaKG:用于构建医学知识图谱的糖尿病标注数据集【命名实体识别(NER)和关系抽取(RE)】
  6. 什么是SFRplus色卡?
  7. 关于php判断美国时间夏令时的问题
  8. 《贫穷克星》PHP源码赚钱项目¥
  9. 20110400笑话
  10. 金蝶eas系统服务器怎么启动,金蝶EAS教你erp是什么,应该怎么去使用