33 个 JavaScript 核心概念系列(四): == 与 ===

原文地址:落明的博客,转载请注明出处!java

JavaScript 中的 == 与 ===

1、前言

做为一个程序员,我想你们在第一次看到 a = b 的语句时必定是懵逼的。后来才知道 = 在编程语言中是用来赋值的,而不是用来判断两个值是否相等。git

那该怎么判断两个值是否相等呢?在 C 或 java 中,是使用 == 来进行比较,而 JavaScript 就有意思了,除了使用 == , 还加了 ===程序员

2、区别与选择

  1. 它们有什么区别?

    具体的区别就一句话:== 在比较时容许进行强制类型转换,而 === 不容许。github

    不少人都担忧 == 作的事情多一些会不会影响比较的速度,说实话,会的,但影响是微秒级别的,彻底能够忽略不计。编程

    不难看出,== 像是 === 的一种更深刻的扩展,所以,知足 === 的值必定知足 ==,反之则不成立。后端

  2. 该如何选择使用它们?

    不少人会建议你坚持使用 === 而不使用 ==, 我认为这是不明智的,有些时候,好比说处理后端返回的数据时,你没法保证对方传来的值到你进行比较的时候仍是预期的那样,此时我以为彻底在能够适当的使用 == 来进行兼容。安全

    总的来讲,当你真的肯定进行比较的值是类型相同的,那就使用 ===,不然,除了几种特殊状况,使用 == 并无什么问题 。bash

3、=== 的比较规则

  1. 基本类型值的比较

    === 的比较规则很简单,对于非对象类型的值,先判断两边的操做数是不是同一类型,若是是,则进行比较,不然,直接返回 false编程语言

    但有两个例外状况:NaN === NaN+0 === -0ui

    // 不一样类型
    '12' === 12; // false
    'a' === true; // false
    null === '12' // false
    null === undefined; // false
    
    // 同类型
    1 === 1; // true
    'a' === 'a'; // true
    false === false; // true
    null === null; // true
    
    //特殊状况
    NaN === NaN; // false
    +0 === -0 // true
    复制代码
  2. 引用类型值的比较

    对于包含引用类型值的比较,仍然会先判断两边的数据类型,若是只有一个是引用类型值,则直接返回 false,若是两边均是引用类型值,则会比较他们的引用地址是否一致。

    const a = {
        m: 'string',
        n: 12
    };
    const b = {
        m: 'string',
        n: 12
    };
    const c = 12;
    
    a === b; // false
    a === c ; // false
    
    const d = a;
    a === d; // true
    复制代码

4、== 的比较规则

一开始说过了,在使用 == 进行比较时,运行对两边的操做数进行强制类型转换,那么问题来了,什么状况下会进行转换?不一样类型的转换规则又是怎样?

MDN 中有这样一张表,用来展现不一样类型值进行 == 判断时的转换规则。

乍一看可能会以为很乱,但仍然是能够分几种状况来归纳这些状况。

在具体分析以前,建议先阅读上一篇文章 显式 (名义) 与 隐式 (鸭子)类型转换 ,由于上图中你能看到有诸如 isFalsy()ToNumber()ToString()ToPrimitive 等抽象方法,使用它们只是为了让你们知道强制转换的方向和结果,而这些也都是上一篇文章讲到的内容。

  1. UndefinedNull 与其它类型值的比较

    咱们看前两行和前两列能够发现:它们只和自身及对方相等,与其余类型值比较均返回 false ....这个大概就是传说中的「黑风双煞」吧!

    你们可能会看到 Object 有一个 isFalse() 方法,这个方法是用来判断参数值是不是假值,这个时候你们可能会有疑问了,对象不是都是真值吗?

    没错,document.all 就是一个假值对象,虽然已经被新的 JavaScript 标准废弃,但你或许会在老的项目中看到它,记住就好。

    因为这俩值的特殊性,后面咱们说“其余类型”值的时候是排除这俩类型的。

  2. Number 类型值与其余类型值比较

    除了上面的黑风双煞,Number 算是相等比较时的大哥,谁想和它比较,就得先转成 Number 类型。

  3. Boolean 类型值与其余类型值比较

    既然有大哥,确定得有小弟,而 Boolean 类型值则身先士卒,以身做则,将大哥的原则贯彻到底,堪称模范小弟!

    其余类型值想和 Boolean 值作比较,Boolean 值摇身一变将本身转成了 Number 类型,哎,你说,别人能怎么办?!

    不管别人怎么说,Boolean 只想作一只安静的舔狗,无怨无悔,一辈子一世。

  4. Object 类型值与其余类型值比较

    Object 做为 JavaScript 中最会假装本身的一种类型,在比较以前谁也摸不透它们的真实身份。也正由于此,它们的日子过得不尽相同。

    在进行比较时,JavaScript 国王会经过 toPrimitive() 方法来揭开他们的真面目,最终你会发现,它们的真实身份多是任意的一种基本类型。

    所以,在最终比较时,它们也将以真实身份与其余类型值比较。

  5. String 类型值与其余类型值比较

    对于 String 类型值来讲,在进行比较时的日子并很差过,毕竟,黑风双煞惹不起,黑社会说话也得听,惟一能让它感觉到生活但愿的,就是在与 Object 这个变色龙进行比较的时候了。

    只有 ObjecttoPrimitive() 后转为字符串的时候它们能够以字符串的规则进行比较,不然,它们就要面临黑风双煞或是黑社会。

5、== 正确的使用方法

github 上有位大神总结了下面这张图:

咱们能够将此当作一份参考。

其实在实际的使用过程当中,只要咱们避免一些特殊的状况,== 的使用仍是安全的。

下面就是七种所谓的特殊状况。

"0" == false; // true -- 晕!
false == 0; // true -- 晕!
false == ""; // true -- 晕!
false == []; // true -- 晕!
"" == 0; // true -- 晕!
"" == []; // true -- 晕!
0 == []; // true -- 晕!
复制代码

如何避免?两个原则:

  1. 若是两边的值中有 true 或者 false,千万不要使用 ==。
  2. 若是两边的值中有 []、"" 或者 0,尽可能不要使用 ==。

6、最后

检验你们成果的时候到了,

  1. 仔细想一想上面七种特殊状况的产生缘由。
  2. 思考下面这些值的比较结果。
[] == ![]; // ?
2 == [2]; // ?
'' == [null] // ?

Number.prototype.valueOf = function() {
 return 3;
};
new Number( 2 ) == 3; // ?

复制代码
相关文章
相关标签/搜索