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

1、语义和场景不同

Undefined 和 Null 是 Javascript 中两种特殊的原始数据类型(Primary Type),它们都只有一个值,分别对应 undefined 和 null 。

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

  • 声明了一个变量,但没有赋值,如 var foo;
  • 访问对象上不存在的属性,如果 Object.foo;

对于场景1,console.log(foo) 时,会返回 undefined,表示这个变量自从声明了以后,就从来没有使用过,也没有定义过任何有效的值,即处于一种原始而不可用的状态。

对于场景2,console.log(Object.foo) 也会返回 undefined,表示Object 上不存在或者没有定义名为 “foo” 的属性。

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

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

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

typeof null == 'object'

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

2、表示的内容相似

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

ECMAScript 规范认为,既然 null 和  undefined 都表示 一个无效的值,那么它们所表示的内容是相似,即有

undefined == null; //true

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

但 === 会返回 false ,因为两者不属于同一种类型:

undefined === null; //false

3、总结和应用

用一句话总结 undefined 和 null 的区别就是,undefined 表示一个变量自然的、最原始的状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。当然,你完全可以手动给一个变量设置为 undefined,但这样做没有意义,因为一个变量不赋值就是 undefined。所以,在实际使用过程中,为了保证变量所代表的语义,不要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。

原创发布 @一像素 2017.08

null == undefined ?的更多相关文章

  1. 当call/apply传的第一个参数为null/undefined的时候js函数内执行的上下文对象是什么呢?

    如题:在js中我们都知道call/apply,还有比较少用的bind;传入的第一个参数都是改变函数当前上下文对象;call/apply区别在于传的参数不同,一个是已逗号分隔字符串,一个以数组形式.而b ...

  2. 【转】Javascript 中的false,零值,null,undefined和空字符串对象

    js 开发中经常会碰到判断是否为空的情况,关于 null 和 undefined 的区别了解的不是很好,刚好看见这篇文章,转过来学习一下,以下是转载正文: 在Javascript中,我们经常会接触到题 ...

  3. javascript 数组 排除null, undefined, 和不存在的元素

    The most common way to loop through the elements of an array is with a for loop: var o = [1,2,3,4,5] ...

  4. Javascript 中的false,零值,null,undefined和空字符串对象

    在Javascript中,我们经常会接触到题目中提到的这5个比较特别的对象--false.0.空字符串.null和undefined.这几个对象很容易用错,因此在使用时必须得小心. 类型检测 我们下来 ...

  5. js中 null, undefined, 0,空字符串,false,不全等比较

    null == undefined // true null == ''  // false null == 0 // false null == false // false undefined = ...

  6. Js 中的false,零值,null,undefined和空字符串对象

    转自  http://www.imkevinyang.com/2009/07/javascript-中的false零值nullundefined和空字符串对象.html 在Javascript中,我们 ...

  7. js null, undefined, NaN, ‘’, false, 0, ==, === 全验证

    <html> <head> <meta charset="utf-8" /> </head> <body> <in ...

  8. call和apply第一个参数为null/undefined,函数this指向全局对象

    call和apply第一个参数为null/undefined,函数this指向全局对象,在浏览器中是window,在node中是global 在严格模式中(ie 6/7/8/9 除外),传入null/ ...

  9. 简写代码:当变量为false时['',false,null,undefined,0,NaN]时,返回默认值

    当变量为'',false,null,undefined,0,NaN时,返回默认值 var a='' a || 'hello world'   "hello world" var a ...

随机推荐

  1. spring注解一次 清除多个缓存

    @Caching(evict = { @CacheEvict(value="cacheName",key="#info.id+'_baojia'",before ...

  2. Web直接导入导出SHP/CAD实现探讨。

    1.导入SHP/CAD文件 WEB具有直接美观展现功能,功能实现到可视化最好不要超过3S,那么就要限制导入文件的大小和优化算法了. 1.1.SHP导入实现思路 SHP格式开源,Git上随便可以找到读取 ...

  3. Linux下配置tomcat+apr+native应对高并发

    摘要:在慢速网络上Tomcat线程数开到300以上的水平,不配APR,基本上300个线程狠快就会用满,以后的请求就只好等待.但是配上APR之后,Tomcat将以JNI的形式调用Apache HTTP服 ...

  4. JQuery——banner旋转木马效果

    博主在浏览网页时无意间发现了一种banner图的轮播方式--像旋转木马一样的轮播方式,博主感觉非常新颖独特,经过查阅资料,观看某课网教程总算搞了出来的,其原理主要利用了JQuery代码实现,好了不多说 ...

  5. 在vs2010中显示代码的行数

    1.打开VS2010,然后"工具" → "选项" 2.在选项页面,点击"文本编辑器"→"所有语言",在显示里将[行号]选 ...

  6. English - Titanium Bike

    The silver-gold triathlon bike was sitting in Kris's dining room next to the door. It had no kicksta ...

  7. Bootstrap按钮插件

    前面的话 按钮插件提供了一组可以控制按钮多种状态的功能,比如按钮的禁用状态.正在加载状态.正常状态等.本文将详细介绍Bootstrap按钮插件 加载状态 通过按钮可以设计状态提示,当单击按钮时,会显示 ...

  8. JavaScript+svg绘制的一个动态时钟

    结果图: 代码如下: <!DOCTYPE html> <html> <head> <title>动态时钟</title> </head ...

  9. A start job is running for xxx to stop

    CentOS7开机时,遇到这样的问题已经好多回了,查阅了许多这样的问题,总是没能找到自己想要的答案. 今天本来启动顺利,但是设置mysql.httpd服务开机启动之后,再次开机时又遇到这样的问题. 这 ...

  10. Spring Boot 系列(三)属性配置&自定义属性配置

    在使用spring boot过程中,可以发现项目中只需要极少的配置就能完成相应的功能,这归功于spring boot中的模块化配置,在pom.xml中依赖的每个Starter都有默认配置,而这些默认配 ...