javascript中的1==[1]是什么?

javascript中的1==[1]是什么?,javascript,arrays,coercion,Javascript,Arrays,Coercion,最近我在一次采访中被问到这个问题 var a = 1; var b = [1]; 什么将a==b返回 当我在chrome浏览器控制台上检查时,我得到了这个 var a = 1; var b = [1]; a == b; true 我也查过了 var a = 1; var b =(1); a == b; true 我知道在一个大小为1的数组中。这是否意味着数组的大小被分配给b。我真的很困惑。谁能给我解释一下逻辑吗 如果将对象与数字或字符串进行比较,JavaScript将尝试返回该对象的默

最近我在一次采访中被问到这个问题

 var a = 1;
 var b = [1];
什么将
a==b返回

当我在chrome浏览器控制台上检查时,我得到了这个

var a = 1;
var b = [1];
a == b;
true
我也查过了

var a = 1;
var b =(1);
a == b;
true
我知道在一个大小为1的数组中。这是否意味着数组的大小被分配给b。我真的很困惑。谁能给我解释一下逻辑吗

如果将对象与数字或字符串进行比较,JavaScript将尝试返回该对象的默认值。运算符尝试使用对象的和方法将对象转换为基本值,即
字符串
数字
值。如果此转换对象的尝试失败,将生成运行时错误。[]

var a=1;
VarB=[1];
//当`(a==b)时发生了什么`
//a的类型;==>数
//类型b;==>对象
//使用对象的'valueOf'和'toString'方法将对象转换为基元
var val=b.valueOf().toString();
console.log('转换后的值为:'+val+',转换后的值的类型为:'+typeof val);
//val的类型;==>一串
//a==b;将计算为'true',因为''1'==1',因此。。

console.log(a==b);/'1'==1==>true
这是由于进行比较的类型

在javascript中,可以使用
=
==
进行比较。在三重相等的情况下,这就是所谓的,换句话说,这是一个严格的比较

与类型强制相等

相反,这意味着使用双等于操作数与类型强制相等

这是什么意思?

简单地说,这意味着javascript将使用内置方法将值转换为基本类型,以便进行比较。具体来说,这些方法是
.valueOf()
.toString()

以下是一些例子:

0 == false   // true, auto type coercion
0 === false  // false, because they are of a different type
1 == "1"     // true, auto type coercion
1 === "1"    // false, because they are of a different type
因此:


从人造丝的回答中,我真的不明白在将对象转换为原始值时,
valueOf
toString
是如何起作用的;所以我深入研究了说明书

警告:回答很长

我们要检查表达式
1==[1]

12.10相等运算符开始我们可以看到,在检索表达式值之后,最后一步是

  • 返回执行抽象相等比较的结果rval==lval
  • 第7.2.12章“抽象相等比较”中定义了抽象相等比较

    7.2.12抽象等式比较
    比较x==y,其中x和y是值,生成true或false。这样的比较如下所示:

  • 返回一个brupt(x)
  • 返回初始值(y)
  • 如果类型(x)与类型(y)相同,则
    A.返回执行严格相等比较的结果x==y
  • 如果x为null而y未定义,则返回true
  • 如果x未定义且y为null,则返回true
  • 如果Type(x)是Number,Type(y)是String,则返回比较结果x==ToNumber(y)
  • 如果Type(x)是String,Type(y)是Number,则返回比较结果ToNumber(x)==y
  • 如果类型(x)是布尔值,则返回比较结果tonNumber(x)==y
  • 如果类型(y)是布尔值,则返回比较结果x==ToNumber(y)
  • 如果类型(x)是字符串、数字或符号,而类型(y)是对象,则 返回比较结果x==ToPrimitive(y)。
  • 如果类型(x)是Object,类型(y)是String、Number或Symbol,则返回比较结果ToPrimitive(x)==y
  • 返回false
  • 表达式
    1==[1]
    属于第10种情况。
    因此,基本上,正如预期的那样,数组
    [1]
    被转换为原语类型的值

    TopPrimitive定义在7.1.1 TopPrimitive(输入[,首选类型])

    抽象操作ToPrimitive接受一个输入参数和一个可选参数PreferredType。这个 抽象操作ToPrimitive将其输入参数转换为非对象类型

    我没有包括完整的报价,因为唯一有趣的,对于本例,,部分是:

  • PreferredType参数(实际上是一个提示变量)从“default”(因为未传递)转换为“number”
  • OrdinaryToPrimitive
    使用相同的参数调用
  • E现在,对于有趣的部分,普通toprimitive执行以下操作:

  • 断言:类型(O)是对象
  • 断言:类型(提示)是字符串,其值是“字符串”或“数字”
  • 如果提示为“字符串”,则
    A.让方法名为«“toString”,“valueOf”»
  • 否则,
    a让方法名为«“valueOf”,“toString”»。
  • 对于methodNames中按列表顺序排列的每个名称,请执行以下操作
    A.让方法为Get(O,name)。
    B返回默认值(方法)。
    C如果IsCallable(method)为true,则
    ... 我让结果被调用(方法,O)。
    ... 二,。返回默认值(结果)。
    ... iii.*如果类型(结果)不是对象,则返回结果。**
  • 抛出TypeError异常

  • 因此,为了将
    [1]
    转换为基本值,运行时首先尝试调用
    valueOf
    。此方法返回数组本身,它是一个对象,因此5.c.iii下一步调用方法
    toString

    此方法以逗号分隔的列表形式返回数组的元素,因此它只返回字符串
    “1”

    因此,我们减少了比较
    1==“1”
    ,根据抽象相等比较规则第6点,这意味着将
    “1”
    转换为数字
    1
    ,而不是执行简单的比较
    1=1

    1 == [1] // true
    1 === [1] // false, because they are of a different type
    
    <html>
        <head><title>title</title></head>
        <body>
            <script>
                var old_valueOf = Array.prototype.valueOf;
                var old_toString = Array.prototype.toString;
    
                Array.prototype.valueOf = function(){ console.log("Array::valueOf"); return old_valueOf.apply(this); };
                Array.prototype.toString = function(){ console.log("Array::toString"); return old_toString.apply(this); };
    
                console.log(1 == [1]); //Array::valueOf, Array::toString, true 
    
                Array.prototype.valueOf = function(){ console.log("Array::valueOf"); return 2; };
    
                console.log(1 == [1]); //Array::valueOf, false 
    
                Array.prototype.valueOf = function(){ console.log("Array::valueOf"); return {}; };
                Array.prototype.toString = function(){ console.log("Array::toString"); return {} };
    
                console.log(1 == [1]); //Array::valueOf, Array::toString, Uncaught TypeError: Cannot convert object to primitive value
            </script>
        </body>
    </html>