Javascript 中的“===”运算符是否对原语和非原语有单独的定义?

Does the `===` operator in Javascript have separate definitions for primitives vs non-primitives?

提问人:RNdev 提问时间:12/5/2022 更新时间:12/5/2022 访问量:56

问:

使用 Javascript 中的运算符,如果它在基元上运算,则如果值不同或类型不同,则返回 false。如果它对非基元进行操作,则如果两个操作数不指向同一对象,则返回 false。===

当应用于基元和非基元时,这似乎有单独的定义。比如“如果操作数是基元,就做这个,否则就做这个”。是否有更广泛的定义,包括对原语和非原语的处理?比如“无论是原始的还是非原始的,都这样做”?======

javascript 相等 原始类型 equality-operator

评论

0赞 Sebastian Simon 12/5/2022
你检查过规格吗?
2赞 slebetman 12/5/2022
他们比较的是值,而不是引用。一旦你以这种方式定义它,两者之间的差异就会消失。对于值类型(字符串、数字、true、false、null),值是其本身。对于引用类型(new String()、数组、对象),值是引用(基本上是变量的地址,而不是变量的内容)。这种区别受到C和C++等较低级别语言的影响。
0赞 slebetman 12/5/2022
请注意,理解引用之间的这种区别(在 C++ 中,这将属于“理解指针”的主题)对于像 和 这样的比较运算符是必要的。赋值在值和引用之间的行为也略有不同。当你赋值时,你会得到一个副本。当您指定引用时,两个变量将指向同一个对象。=====

答:

1赞 Mike 'Pomax' Kamermans 12/5/2022 #1

这里唯一真正的答案是规范,我们看到定义:===

EqualityExpression : EqualityExpression === RelationalExpression

 1. Let lref be ? Evaluation of EqualityExpression.
 2. Let lval be ? GetValue(lref).
 3. Let rref be ? Evaluation of RelationalExpression.
 4. Let rval be ? GetValue(rref).
 5. Return IsStrictlyEqual(rval, lval).

因此,我们比较的是“无论 GetValue 规范函数说我们应该比较什么”,再加上“我们必须为此使用严格的相等性测试”,所以我们不是在比较“两个原始值,或两个引用”。还涉及一些步骤,在大多数情况下,这些步骤与“实际使用 JS”无关,因此出于实际目的,它们根本不重要......但是当你有基本问题时,规范就是基础=)

3赞 CertainPerformance 12/5/2022 #2

是的,在某种程度上 - 这里有一些过程。

7.2.15 IsStrictlyEqual ( x, y )

  1. 如果 Type(x) 与 Type(y) 不同,则返回 false。
  2. 如果 x 是 Number,则返回 Number::equal(x, y)。
  3. 返回 SameValueNonNumber(x, y)。

7.2.12 SameValueNonNumber ( x, y )

  1. 断言:Type(x) 与 Type(y) 相同。
  2. 如果 x 是 BigInt,则 a.a. 返回 BigInt::equal(x, y)。
  3. 如果 x 未定义,则返回 true。
  4. 如果 x 为 null,则返回 true。
  5. 如果 x 是 String,则 一个。如果 x 和 y 是完全相同的代码单元序列(相同长度和相同索引处的相同代码单元),则返回 true;否则,返回 false。
  6. 如果 x 是布尔值,则 一个。如果 x 和 y 均为 true 或均为 false,则返回 true;否则,返回 false。
  7. 如果 x 是符号,则 一个。如果 x 和 y 都是相同的 Symbol 值,则返回 true;否则,返回 false。
  8. 如果 x 和 y 是相同的 Object 值,则返回 true。否则,返回 false。