当前位置:首页 > 科技  > 软件

JS 中 == 不检查类型?不,你错了!

来源: 责编: 时间:2024-04-12 17:30:06 94观看
导读Hello,大家好,我是 Sunday。我们知道在 JS 中有两种判断相等的方式,即:== 和 ===。并且很多同学会认为“==”运算符(通常称为“松散相等”或简称“相等”)是不精准的。“==”不关心数据类型,只关心值例如如下代码:1 == '1' //

Hello,大家好,我是 Sunday。ban28资讯网——每日最新资讯28at.com

我们知道在 JS 中有两种判断相等的方式,即:== 和 ===。并且很多同学会认为“==”运算符(通常称为“松散相等”或简称“相等”)是不精准的。ban28资讯网——每日最新资讯28at.com

“==”不关心数据类型,只关心值ban28资讯网——每日最新资讯28at.com

例如如下代码:ban28资讯网——每日最新资讯28at.com

1 == '1' // true

而“===”运算符,即“严格相等”,可以有效地验证操作数的值和类型:ban28资讯网——每日最新资讯28at.com

1 === '1' // false

但是这种理解真的是完全正确的吗?最近有一个同学在面试的时候被深入问到了这个问题,咱们来看一下:ban28资讯网——每日最新资讯28at.com

“==”和“===” 的执行逻辑

先说结论,其实:“==”和“===”这两个运算符都优先考虑数据类型,并在执行各自的算法之前执行类型检查。事实上,即使是“==”运算符在评估值之前也会验证类型。ban28资讯网——每日最新资讯28at.com

根据 JavaScript 规范参考 ECMAScript 262 文档,概述了 IsLooselyEqual算法 ,负责处理“==”操作。这里说明了涉及 14 个步骤的综合过程。值得注意的是,这个过程大量涉及类型检查,如涉及Type(x)的初始步骤所证明的那样,并引入强制作为整个操作的重要方式。ban28资讯网——每日最新资讯28at.com

图片图片ban28资讯网——每日最新资讯28at.com

下方描述为翻译后的结果ban28资讯网——每日最新资讯28at.com

// 在线地址:https://262.ecma-international.org/14.0/?_gl=1*1ddd25w*_ga*MTAzMTk1MjUwNS4xNzA0MTgwNDk0*_ga_TDCK4DWEPP*MTcwNDE4MDQ5NC4xLjAuMTcwNDE4MDQ5NC4wLjAuMA..&_ga=2.72864531.1838071013.1704180495-1031952505.1704180494#sec-islooselyequal7.2.14 松散相等 ( x, y )抽象操作 IsLooselyEqual 接受参数 x(ECMAScript 语言值)和 y(ECMAScript 语言值),并返回包含布尔值的正常完成或抛出完成。 它提供 == 运算符的语义。 调用时它执行以下步骤:1. 如果 Type(x) 是 Type(y),则A。 A。 返回 IsStrictlyEqual(x, y)。2. 如果 x 为 null 并且 y 未定义,则返回 true。3. 如果 x 未定义且 y 为 null,则返回 true。4. 注意:此步骤已在 B.3.6.2 节中替换。5. 如果 x 是数字且 y 是字符串,则返回! IsLooselyEqual(x, !ToNumber(y))。6. 如果 x 是字符串且 y 是数字,则返回! IsLooselyEqual(!ToNumber(x), y)。7. 如果 x 是 BigInt 并且 y 是 String,则A。 令 n 为 StringToBigInt(y)。b. 如果 n 未定义,则返回 false。C。 返回 ! IsLooselyEqual(x, n)。8. 如果 x 是 String 并且 y 是 BigInt,则返回! IsLooselyEqual(y, x)。9. 如果 x 是布尔值,则返回! IsLooselyEqual(!ToNumber(x), y)。10. 如果 y 是布尔值,则返回! IsLooselyEqual(x, !ToNumber(y))。11. 如果 x 是字符串、数字、BigInt 或符号并且 y 是对象,则返回! IsLooselyEqual(x, ? ToPrimitive(y))。12. 如果 x 是对象并且 y 是字符串、数字、BigInt 或符号,则返回! IsLooselyEqual(? ToPrimitive(x), y)。13. 如果 x 是 BigInt 并且 y 是 Number,或者如果 x 是 Number 并且 y 是 BigInt,则A。 A。 如果 x 不是有限的或 y 不是有限的,则返回 false。b. b. 如果 ℝ(x) = ℝ(y),则返回 true; 否则返回 false。14. 返回 false。

强制转换涉及将一种类型的值转换为另一种类型,可以通过有意操作显式转换,也可以通过 JavaScript 机制隐式转换,无需任何用户干预。ban28资讯网——每日最新资讯28at.com

另外一个有趣的方法,当两种类型匹配时,将使用 IsStrictlyEqual 算法(步骤 1.a),该算法与“===”运算符使用的算法完全相同。ban28资讯网——每日最新资讯28at.com

图片图片ban28资讯网——每日最新资讯28at.com

翻译之后为:ban28资讯网——每日最新资讯28at.com

// 在线地址:https://262.ecma-international.org/14.0/?_gl=1*1ddd25w*_ga*MTAzMTk1MjUwNS4xNzA0MTgwNDk0*_ga_TDCK4DWEPP*MTcwNDE4MDQ5NC4xLjAuMTcwNDE4MDQ5NC4wLjAuMA..&_ga=2.72864531.1838071013.1704180495-1031952505.1704180494#sec-isstrictlyequal7.2.15 IsStrictlyEqual(x,y)抽象操作 IsStrictlyEqual 接受参数 x(ECMAScript 语言值)和 y(ECMAScript 语言值)并返回布尔值。 它提供 === 运算符的语义。 调用时它执行以下步骤:1. 如果 Type(x) 不是 Type(y),则返回 false。2. 如果 x 是一个数字,那么A。 返回 Number::equal(x, y)。3. 返回 SameValueNonNumber(x, y)。

让我们深入研究 IsLooselyEqual的第五步(如果 x 是数字且 y 是字符串,则返回! IsLooselyEqual(x, !ToNumber(y))):ban28资讯网——每日最新资讯28at.com

图片图片ban28资讯网——每日最新资讯28at.com

根据提供的代码片段ban28资讯网——每日最新资讯28at.com

1 == "1"  // true // x 是数字 (1) // y 是字符串 ("1")

此处,调用 ToNumber (y)函数时会发生隐式 强制转换。此强制过程将值(y,即“1”)从其原始类型(在本例中为String)转换为不同的类型(在本例中为Number)。在比较值之前,此步骤涉及类型检查和强制,将两个值对齐到同一类型(Number),从而实现两个数字之间的直接比较。ban28资讯网——每日最新资讯28at.com

1 == "1"  // true //步骤 1。// -> 检查两种类型// -> 两种类型不同// -> 执行 IsLooselyEqual 的后续步骤//步骤 2。   // -> "1 " (String) 将变成 1 (Number) - 强制机制//Step 3.   // -> 将值 1(数字,从左侧)与值 1(数字,在右侧)进行比较

在这种情况下,严格相等运算符将返回 false,如前面提供的内容所示。由于两种类型不同,因此 === 会判定为 false:ban28资讯网——每日最新资讯28at.com

1 === "1"  // false //步骤 1.   // -> 检查两种类型// -> 两种类型不同// -> 结束进程,返回 false

总结

两个比较运算符都会检查类型,但松散的相等运算符(==) 需要执行额外的步骤。ban28资讯网——每日最新资讯28at.com

  • 它首先检查比较值的类型,如果它们不同,则将它们对齐到相同类型(使用隐式强制),
  • 然后继续进行值比较。 使用严格相等运算符(===)时,不涉及该额外步骤。在值不同的情况下,它直接返回 false。

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-83277-0.htmlJS 中 == 不检查类型?不,你错了!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Python备份数据有哪些库

下一篇: 前端神器AbortController:深度解析与实战应用

标签:
  • 热门焦点
Top
Baidu
map