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>