先用最近遇到的几个问题做引子:

    1 console.log(null==undefined); //true
2 console.log(null==false);//false
3 console.log(null==0);//false
4 console.log(0==undefined);//false
5 console.log(false==undefined); //false
6 console.log([]==![]);//true

各位读者如果不确定的话,可以在各自的浏览器中实验一下。

怎么样?答案和自己想的一致吗?如果不一致,那就跟随笔者探索一下其中的奥秘吧!

首先我们来分析一下undefinednull的区别。

首先来看下面这个例子:

    Number(null)
//0
10+null
//10

这样看来,null被设计成可以自动转为0.

JavaScript的最初版本是这样区分的,null是一个表示“无”的对象,转为数值时为0;undefined是一个表示“无”的原始值,转为数值时为NaN。

null表示“没有对象”,即该处不应该有值。典型用法是:

  • 作为函数的参数,表示该函数的参数不是对象。

  • 作为对象原型链的终点。

     Object.getPrototypeOf(Object.prototype)
    // null

undefined表示“缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:

  • 变量被声明了,但没有赋值时,就等于undefined。

  • 调用函数时,应该提供的参数没有提供,该参数等于undefined。

  • 对象没有赋值的属性,该属性的值为undefined

  • 函数没有返回值时,默认返回undefined

      var i;
    i //undefined function f(x){console.log(x)}
    f() //undefined var o=new Object();
    o.p //undefined var x=f();
    x //undefined

那么为什么null==undefined呢?

ECMAScript认为,undefined是从null派生出来的,所以把它们定义为相等的。但是,如果在一些情况下,我们一定要区分这两个值,那应该怎么办呢?可以使用下面的两种方法。

    alert(null===undefined);
alert(typeof null == typeof undefined)

此时,我们已经解决了第5个问题,那么其他的如何解释呢?

下面是摘自stackflow上大神的解释。

The Abstract Equality Comparison Algorithm

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

  1. If Type(x) is the same as Type(y), then

    1.1 If Type(x) is Undefined, return true.

    1.2 If Type(x) is Null, return true.

    1.3 If Type(x) is Number, then

    • If x is NaN, return false.

    • If y is NaN, return false.

    • If x is the same Number value as y, return true.

    • If x is +0 and y is −0, return true.

    • If x is −0 and y is +0, return true.

    • Return false.

    1.4 If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.

    1.5 If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.

    1.6 Return true if x and y refer to the same object. Otherwise, return false.

  2. If x is null and y is undefined, return true.

  3. If x is undefined and y is null, return true.

  4. If Type(x) is Number and Type(y) is String,return the result of the comparison x == ToNumber(y).

  5. If Type(x) is String and Type(y) is Number,return the result of the comparison ToNumber(x) == y.

  6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

  7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

  8. If Type(x) is either String or Number and Type(y) is Object,return the result of the comparison x == ToPrimitive(y).

  9. If Type(x) is Object and Type(y) is either String or Number,return the result of the comparison ToPrimitive(x) == y.

基于以上规则,我们再来看看最初的题目:

以第6题为例:

[]是数组,而![]是boolean值。当你使用==比较两个不同类型的对象时需要转化为可比较的类型,根据上述规则第7条,使用ToNumber转化后,![]返回0,[]返回0,所以为true。

深入探究JavaScript中的比较问题的更多相关文章

  1. 探究JavaScript中的五种事件处理程序

    探究JavaScript中的五种事件处理程序 我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务 ...

  2. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  3. Javascript中String()与new String()的差异

    这里主要关注的是值类型和引用类型. 我们知道在javascript中的变量在内存中的存储有两种形式,值类型存储和引用类型存储. 通常可以进行值存储的包括  字符串类型,布尔值类型,数字类型,他们都包含 ...

  4. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  5. JavaScript中以构造函数的方式调用函数

    转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明. ...

  6. javascript中var、let和const的区别

    在javascript中,var.let和const都可以用来声明变量,那么三者有什么区别呢?要回答这个问题,我们可以从先想想:三种不同的声明会影响变量的哪些方面?这些方面也就是变量的特性,那么变量有 ...

  7. Javascript中的继承与Prototype

    之前学习js仅仅是把w3school上的基本语法看了一次而已,再后来细看书的时候,书中会出现很多很多没有听过的语法,其中一个就是js的继承以及总能看到的prototype.我主要在看的两本js书是&l ...

  8. 漫谈JavaScript中的提升机制(Hoisting)

    前言 刚接触到JavaScript的时候,便知道JavaScript是按顺序执行的,是如浏览器的解析DOM树一样的流程,解析DOM结构的时候,如果遇到JS脚本或者外联脚本便会停止解析,继续下载脚本之后 ...

  9. 详解JavaScript中的原型

    前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...

随机推荐

  1. phpcms 源码分析三:common.inc.php

    这次是逆雪寒分析common.inc.php的数据库部分: <?php // 包含数据库操作类,下章详说 require PHPCMS_ROOT.'/include/'.$db_file.'.c ...

  2. Android 开发第四天

  3. c语言,strcmpi(),将一个串中的一部分与另一个串比较, 不管大小写

    #include<stdio.h> #include<string.h> 函数名: strncmpi 功 能: 将一个串中的一部分与另一个串比较, 不管大小写 用 法: int ...

  4. MyBatis自动获取主键,MyBatis使用Oracle返回主键,Oracle获取主键

    MyBatis自动获取主键,MyBatis使用Oracle返回主键,Oracle获取主键 >>>>>>>>>>>>>> ...

  5. C++ 全排列函数 nyoj 366

    C++ STL中提供了std::next_permutation与std::prev_permutation可以获取数字或者是字符的全排列,其中std::next_permutation提供升序.st ...

  6. python tornado+mongodb的使用

    tornado tar xvzf tornado-1.2.1.tar.gz cd tornado-1.2.1 python setup.py build sudo python setup.py in ...

  7. Struts2 多文件下载

    Step1:导入支持jar包 commons-fileupload-1.3.1.jar commons-io-2.4.jar jstl-1.2.jar standard-1.1.2.jar commo ...

  8. OC 知识点回顾

    /* 字符串: NSString  不可变字符串  字符串对象的内容不能修改,字符串的指针可以改变 NSMutableString 可变字符串   可以修改字符串对象的内容,继承自NSString , ...

  9. TreeListView的用法

    public void ProductBind() { tlvProduct.Items.Clear(); List<ProductInfo> list = ppbll.GetProduc ...

  10. SDL实现限制帧速

    很多人都在SDL_PollEvent和SDL_WaitEvent之间纠结.前者会带来更好的帧数表现,但是CPU占用极大,可以直接吃掉一个核心.后者则基本不占用CPU,但是帧数会受到影响.有没有办法使两 ...