如果数组在JavaScript中是真实的,为什么不等于true?

zul*_*luk 4 javascript arrays comparison javascript-objects

我有以下代码片段:

if([]) {
  console.log("first is true");
}
Run Code Online (Sandbox Code Playgroud)

console说,first is true该装置[]是真实的。现在我想知道为什么:

if([] == true) {
  console.log("second is true");
}
Run Code Online (Sandbox Code Playgroud)

和这个:

if([] === true) {
  console.log("third is true");
}
Run Code Online (Sandbox Code Playgroud)

不是true。如果控制台登录first is true了第一个代码段,那意味着[]应该为真,对吗?那么为什么后两个比较失败?是小提琴。

Li3*_*357 6

这是根据规范。根据ECMAScript 2015语言规范,隐式强制转换为布尔值的任何对象均为true;这意味着物体是真实的。在if语句内部,条件一旦被评估并且如果不是布尔值,就被强制为布尔值。因此,请执行以下操作:

if([]) { 
  ... 
}
Run Code Online (Sandbox Code Playgroud)

[] 强制为布尔值时为true,并且为true。

另一方面,当您尝试使用抽象比较比较不同类型的两个值时==,引擎必须在内部进行算法以将值减少为相似类型,最终将其简化为可以比较的整数。在规范的7.2.12节中,关于“抽象相等比较”的步骤x == y,指出:

7.2.12抽象平等比较

比较x == y(其中xy是值)产生truefalse。这样的比较执行如下:

[...]

  1. 如果Typey)为布尔型,则返回比较结果x == ToNumbery)。

因此,y操作数(在这种情况下为true)通过强制转换为1,ToNumber因为它是布尔值,并且[] == 1是假的,因为:

  1. 如果Typex)是Object并且Typey)是String,Number或Symbol,则返回比较结果ToPrimitivex== y

这将x使用toString数组的方法将操作数转换为字符串,""在这种情况下,该方法适用于空数组。经过后ToPrimitive,将导致:

if("" == 1) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

最后:

  1. 如果Typex)是String且Typey)是Number,则返回比较结果ToNumberx== y

因此,ToNumber一个空字符串""为0,您将获得:

if(0 == 1) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

0不等于1,因此为假。请记住,仅仅因为某件事是真实的,并不等于真实。请尝试Symbol() == true({}) == true

最终比较with ===严格比较,并且不强制任何操作数,并且如果两个操作数不是同一类型,则将返回false。由于左操作数是一个对象(一个数组),而右操作数是一个数字,因此比较结果为false。