js面试系列: `==`和 `===`的区别

前言

春招在即,时间十分可贵,今天本人继续带大家来探秘js系列的考题,之前我们已经讲过了js考题中的类型转换机制,现在让我们来探索js中的等值操作符吧。

等值操作符

==(等于操作符)

等值操作符是我们经常会使用的等值比较方法,我们都是用(==)两个等号来进行表示的,如果等号两边的数相等的话,就会返回true

在之前的文章js的类型转换机制中,我们已经介绍过JavaScript中存在着隐式转换机制。当我们使用等于操作符(==)时,在比较过程中,就会进行类型转换,再来确定值是否相等。 如:

js 复制代码
let a = (true == 1) //true
let b = ("2" == 2) //true
let c = (null == undifined) //true

但是等于操作符在遇到与引用类型相关的类型转换时,会有所不同。在将引用类型转换为原始值时,JavaScript 会调用对象的 valueOf()toString() 方法,以便获取一个原始值。这两个方法的返回值会根据需要进行转换。JavaScript 引擎首先尝试调用对象的 valueOf() 方法,如果返回的值不是原始值(即对象),则继续尝试调用 toString() 方法。如果 toString() 方法返回的值是原始值,则使用该值进行比较。

下面是具体的转换过程:

  1. 如果对象具有 valueOf() 方法且返回的值是原始值(非对象),则直接使用该值进行比较。
  2. 如果对象没有 valueOf() 方法,或者 valueOf() 返回的是对象,那么 JavaScript 将调用对象的 toString() 方法。
  3. 如果对象具有 toString() 方法且返回的值是原始值(非对象),则直接使用该值进行比较。
  4. 如果对象没有 toString() 方法,或者 toString() 返回的是对象,则会抛出 TypeError 错误。

注意: valueOf() 只能将包装类的对象转换为原始类型

[] == ![]

在面试中,[] == ![] 也是一个十分常考的点,它也与上面的等值操作中的引用类型转换相关。 现在来解释 [] == ![] 是如何进行判断的:

  1. 首先,![] 运算符 ! 是逻辑非操作符,它会将其操作数转换为Boolean类型,然后取其相反值。由于 [] 是一个非空的数组,转换为Boolean类型后为 true,所以 ![] 的值为 false
  2. 然后,根据运算符优先级,==! 优先级高,所以 ![] 会先计算出结果 false
  3. 接着,[]false 进行比较。根据相等运算符的规则,在进行比较之前,JavaScript 会尝试将两个值转换为相同的类型。因为 [] 是一个对象(数组),而 false 是一个布尔值,所以 JavaScript 会将 [] 转换为一个原始值。
  4. 数组 [] 转换为原始值时会调用其 toString() 方法,将其转换为一个空字符串 ""。然后,空字符串 "" 转换为数字时会变成 0
  5. 所以最终的比较变成了 0 == false
  6. 在比较过程中,布尔值 false 会被转换为数字 0。因此,这个比较最终变成了 0 == 0
  7. 最终结果是 true

注意: 任何引用类型转boolean都是true

===(恒等操作符)

在JavaScript中恒等操作符也称为(### 严格相等运算符)由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同。如:

js 复制代码
let a = (true === 1) //false
let b = ("2" === 2) //false
let c = (null === undifined) //false

从以上示例中,我们可以看出,=== 恒等操作符,在比较两边的两个值时,会比较两个值是否严格相等,不会进行类型转换。只有在两个值的类型相同且值也相等的情况下,才会返回 true

区别

  1. 类型转换: == 运算符会进行类型转换,而 === 运算符不会进行类型转换。
  2. 比较结果: == 运算符在某些情况下会产生不直观的比较结果,而 === 运算符始终提供更严格的比较。

总结

  • 相等操作符 ==

    • 使用两个等号 == 进行比较时,会进行类型转换,然后再比较值是否相等。
    • 在比较过程中,引用类型会先尝试调用 valueOf() 方法,然后再调用 toString() 方法,将其转换为原始值进行比较。
    • 示例:[] == ![],在比较过程中,数组会被转换为空字符串,然后再转换为数字 0,最终比较结果为 0 == 0,返回 true
  • 严格相等操作符 ===

    • 使用三个等号 === 进行比较时,不会进行类型转换,严格比较两个值的类型和值是否完全相同。
    • 只有在类型和值都相同的情况下才会返回 true
    • 示例:true === 1,因为类型不同,返回 false

综上所述,=== 运算符通常更安全,因为它可以避免因类型转换而导致的意外行为。因此,在可能的情况下,推荐使用 === 运算符进行比较。

相关推荐
Danny_FD1 小时前
Vue2 + Node.js 快速实现带心跳检测与自动重连的 WebSocket 案例
前端
uhakadotcom1 小时前
将next.js的分享到twitter.com之中时,如何更新分享卡片上的图片?
前端·javascript·面试
韦小勇1 小时前
el-table 父子数据层级嵌套表格
前端
奔赴_向往1 小时前
为什么 PWA 至今没能「掘进」主流?
前端
小小愿望1 小时前
微信小程序开发实战:图片转 Base64 全解析
前端·微信小程序
掘金安东尼1 小时前
2分钟创建一个“不依赖任何外部库”的粒子动画背景
前端·面试·canvas
电商API大数据接口开发Cris1 小时前
基于 Flink 的淘宝实时数据管道设计:商品详情流式处理与异构存储
前端·数据挖掘·api
小小愿望1 小时前
解锁前端新技能:让JavaScript与CSS变量共舞
前端·javascript·css
程序员鱼皮1 小时前
爆肝2月,我的 AI 代码生成平台上线了!
java·前端·编程·软件开发·项目
天生我材必有用_吴用1 小时前
一文搞懂 useDark:Vue 项目中实现深色模式的正确姿势
前端·vue.js