请回答下列问题
[] == false
![] == false
'true' == ['true']
true == ['true']
{} + []
[] + {}
[] + []
隐式转换
==
比较运算
== 是隐式转换的常见场景之一,了解它可以解决许多笔试中不应该出错的问题。比如解决[] == false
和![] == false
为什么都为true
.
首先,什么时候会触发隐式转换,在 == 中,当两种数据类型不一样时,就会触发隐式转换
我总结了一个简单的转换规则:在 == 两边如果有对象,对象会先转换为字符串,如果此时数据类型还是不一样,字符串和布尔值再会转换为number类型。
比如:
'true' == ['true']
中,['true'] => 'true'
,所以'true' == 'true'
结果为truetrue == ['true']
中,['true'] => 'true',然后'true' => NaN,而true => 1
,所以1 == NaN
结果为false- 同理
[] == false
,[]
先转换为字符串''
,''和false
再都转换为0
,结果为true ![] == false
是因为需要先计算![]
取反将其转换成布尔值,因为除了(''),NaN,0,null,undefined
转换成布尔值都为false
。[]
转换成布尔值为true
,取反为false
,所以false==false,结果为true
注意:除了以上比较通用的对比方法,还有两个特殊的,null和undefined。Javascript规范中提到,要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,并且规定null 和 undefined 是相等的。所以null 和undefined与其他的相比都是false,只有与其本身和null == undefined 才为true
+,-,*,/,%
运算
运算符+,-,*,/,%
会出现隐式转换
不过很容易理解,运算符,只有数字才能运算。所以基本都是隐式转换为number类型
特殊的+
运算符,因+
有字符串拼接的左右,所有,当运算+
的时候,如果两边存在字符串,是隐式转换为string类型
'+'运算符
常见的字符串拼接,加法运算
如果不会,建议重学
注意:任何Number与NaN相加都为NaN。 虽然null == undefined为true。但是Number(null)为0,Number(undefined)为NaN 所以,null + Number 等于 Number,但undefined+ Number 等于 NaN
转数值 只对null、""、布尔值、数值字符串、长度为1的数组并且数组内的值为数值或数值字符串、拥有valueOf方法并且返回的值为数值或数值字符串的对象,有效,其他均只能转为NaN
const num1 = +null;
const num2 = +"";
const num3 = +false;
const num4 = +true;
const num4 = +"123";
const num5 = +['321'];
const num6 = +{valueOf: function(){
return '456';
}}
// num1 num2 num3 num4 num5 num6 => 0 0 1 123 321 456
特殊现象
String({})为"[object Object]"
{} + [] => 0
[] + {} => "[object Object]"
[] + [] => ""
{} + {} => "[object Object][object Object]"
123 + {} => "123[object Object]"
'123' + {} => "123[object Object]"
{} + '123' => 123
目前还不是很清楚这种情况出现的理论知识,我是这样理解的当式子中只有一个{}时,并且当{}位于式子开头,认为{}是空的代码块,所以{} + []和{} + '123'变成+[]和+'123'
其他几项很明显进行了隐式转换,对象先转换成字符串,然后就直接做了字符串拼接。
对象的转换String(对象)和Number(对象)
var obj = {
valueOf: function(){
return 1;
},
toString: function(){
return 2;
}
};
var obj1 = {
valueOf: function(){
return 'a';
},
toString: function(){
return 'b';
}
};
var obj2 = {
toString: function(){
return 3;
}
};
var obj3 = {
valueOf: function(){
return 'aa';
},
};
console.log(Number(obj),String(obj),Number(obj1),String(obj1),Number(obj2),String(obj3))
// 1 "2" NaN "b" 2 "[object Object]"
//很明显能够看出Number方法会先调用valueOf(),如果没有再会去调用toString(),然后再次valueOf()
//而String方法只会调用toString(),没有找到,抛出类型