博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
33 个 JavaScript 核心概念系列(四): == 与 ===
阅读量:6032 次
发布时间:2019-06-20

本文共 2835 字,大约阅读时间需要 9 分钟。

原文地址:,转载请注明出处!

一、前言

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

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

二、区别与选择

  1. 它们有什么区别?

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

    很多人都担心 == 做的事情多一些会不会影响比较的速度,说实话,会的,但影响是微秒级别的,完全可以忽略不计。

    不难看出,== 像是 === 的一种更深入的扩展,因此,满足 === 的值一定满足 ==,反之则不成立。

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

    很多人会建议你坚持使用 === 而不使用 ==, 我认为这是不明智的,有些时候,比如说处理后端返回的数据时,你无法保证对方传来的值到你进行比较的时候还是预期的那样,此时我觉得完全在可以适当的使用 == 来进行兼容。

    总的来说,当你真的确定进行比较的值是类型相同的,那就使用 ===,否则,除了几种特殊情况,使用 == 并没有什么问题 。

三、=== 的比较规则

  1. 基本类型值的比较

    === 的比较规则很简单,对于非对象类型的值,先判断两边的操作数是否是同一类型,如果是,则进行比较,否则,直接返回 false

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

    // 不同类型'12' === 12; // false'a' === true; // falsenull === '12' // falsenull === undefined; // false// 同类型1 === 1; // true'a' === 'a'; // truefalse === false; // truenull === 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; // falsea === c ; // falseconst d = a;a === d; // true复制代码

四、== 的比较规则

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

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() 后转为字符串的时候它们可以以字符串的规则进行比较,否则,它们就要面临黑风双煞或是黑社会。

五、== 正确的使用方法

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

我们可以将此当做一份参考。

其实在实际的使用过程中,只要我们避免一些特殊的情况,== 的使用还是安全的。

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

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

如何避免?两个原则:

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

六、最后

检验大家成果的时候到了,

  1. 仔细想想上面七种特殊情况的产生原因。
  2. 思考下面这些值的比较结果。
[] == ![]; // ?2 == [2]; // ?'' == [null] // ?Number.prototype.valueOf = function() { return 3;};new Number( 2 ) == 3; // ?复制代码
你可能感兴趣的文章
SSH的整合
查看>>
CDH(Cloudera)与hadoop(apache)对比
查看>>
【Mongodb】如何创建mongodb的replica set
查看>>
玩聚的博客墙 V
查看>>
ARM9学习笔记之——MiniOS
查看>>
WebService应用:音乐站图片上传
查看>>
【HBase】start master 与 start master --backup 的区别
查看>>
Charles中如何对https抓包
查看>>
Spring Cache 介绍
查看>>
一个Android项目多线程下载模块开源库:AndroidFileDownloader
查看>>
项目重构之数据源配置与优化:log4j 配置数据库连接池Druid,并实现日志存储到数据库...
查看>>
iOS版微软自拍App上架:自然美颜 上手简单
查看>>
HDU 1006 Digital Roots
查看>>
一起Polyfill系列:Function.prototype.bind的四个阶段
查看>>
wcf系列学习5天速成——第四天 wcf之分布式架构
查看>>
[HTTP]HTTP协议的状态码
查看>>
Drill官网文档翻译五:连接到数据源
查看>>
[华为机试练习题]13.火车进站
查看>>
linux ubuntu ElasticSearch 安装 基本使用
查看>>
第2章番外 Java的命名规范
查看>>