为什么JavaScript中的“== == true?

我知道JavaScript有许多types之间的比较疯狂的结果,但我不完全明白为什么。 今天来到这一个。

为什么

"" == [null] 

在JavaScript中评估为true

更多的Javascript平等娱乐,感谢@ Qantas:

  • 为什么JavaScript 2中的2 == [2]?
  • 为什么在JavaScript中为0 ==“”为true
  • 为什么如果([])在javascript中validation[] == false?
  • 为什么在JavaScript中将{} [true]评估为true?

“抽象平等比较algorithm”有很多部分,但重要的是:

如果Type( x )是String或Number,Type( y )是Object,则返回比较结果x == ToPrimitive( y )。

(这里也有一个镜像。)所以,因为""是一个string, [null]是一个对象,我们必须先调用ToPrimitive([null])[null]转换为一个string。 当要求将Object实例转换为原始值时,这是一个内部操作,如下所述:

返回对象的默认值。 通过调用对象的[[DefaultValue]]内部方法来检索对象的默认值,并传递可选的提示PreferredType 。 本规范针对8.12.8中的所有本地ECMAScript对象定义了[[DefaultValue]]内部方法的行为。

现在,[[DefaultValue]]内部操作将在对象上调用.toString()并返回该值。 在浏览器控制台中尝试[null].toString()

 > [null].toString() "" 

在那里,你有它。

编辑:为什么是[null].toString()一个空string? 因为Array实例上的.toString()操作总是调用.join() ,并且对于nullundefined值总是会产生一个空string。 因此,一个null的数组最终只是一个空string。

这是根据JavaScript的神秘的types转换规则。 规则#8:

如果Type(x)是String或Number而Type(y)是Object,则返回比较结果x == ToPrimitive(y)。

因此,使用ToPrimitive x = ""y = [null]之间的比较转换为string。 用一个空元素转换数组会导致一个空string(因为Array.toString()返回一个以逗号分隔的值列表),因此它们的计算结果是相等的。

为什么"" == [null]评估为真?

因为你正在比较一个数组与string,使用非严格的相等运算符== – 所以它会尝试在比较之前将值转换为相同的types。

具体发生的是:

  1. 您将一个string与一个对象进行比较,以便将该对象转换为string:
  2. 当一个数组被转换为原始值时,调用.toString()方法(如其他答案所详细解释的),这相当于调用.join()
  3. 在仅包含undefinednull值的单元素数组的情况下, 返回空string
  4. 最后相当于空string

这第三步是意想不到的( [null]+"" != null+"" ),如果它实际上把它转换成string,结果将是"null"并且你的等号是false。

让我们看看规范,并按照每一步

通过抽象平等比较algorithm(§11.9.3) :

  1. typeof ""; // string typeof ""; // stringtypeof [null]; // object typeof [null]; // object不适用
  2. 既不是null也不是undefined所以不适用
  3. 与2相同
  4. 既不是一个数字,也不适用
  5. 和4一样
  6. 既不是一个布尔,也不适用
  7. 再次不适用
  8. 最后,适用的东西,现在我们需要知道ToPrimitive([null])

§9.1ToPrimitive 对象说我们需要制定[[DefaultValue]] (§8.12.8) ,其中的第一点和第二点说如果你可以做.toString ,它给出一个string,返回这个

 [null].toString(); // "" 

所以我们现在正在执行比较"" == ""这是true 的抽象相等比较algorithm的第1点。

如果Type(x)String ,则返回true如果xy是完全相同的字符序列(相同长度和相同位置的相同字符)。 否则,返回false

JavaScript是弱types的; 您可以使用以下来获得一个错误的结果:

 "" === [null] 

null值是表示null或“空”值的JavaScript文字,即没有对象值存在。 这是JavaScript的原始值之一。

null值是一个文字(不是像undefined这样的全局对象的属性)。 在API中,通常会在可以预期对象的位置检索null,但是没有对象是相关的。 当检查null或undefined时,要小心等号(==)和身份(===)运算符(types转换与前者执行)之间的差异。

 typeof null // object (bug in ECMAScript, should be null) typeof undefined // undefined null === undefined // false null == undefined // true