更新自己总结的,之前是看其他帖子,总感觉混乱,
题目分为两种,一种是四则运算,另一种是==判断true还是false的
对于 == 判断的题目
自己总结以下几点
- 以 { } == 开头的,会报错,因为 { } 会被当做代码块,这样写相当于直接写了 == ,识别不出,但是{ } == { } 和 { } == !{ }可以有结果,我也不知道为什么
- 有!的,!的优先级最高,先处理有!的一边,规则是将变量转换成boolean类型,null、undefined、NaN以及空字符串(’’)取反都为true,其余都为false,比如 ! [ ] 转为 false , ! { } 转为 false
- 转完上一步后,两边中有复杂对象的,先把复杂对象转为string,比如 [ ] => ‘’ , [ null ] => ‘’ , { } => “[object Object]”
- 这个时候,两边剩下的都是简单类型变量,如果类型一样,就直接判断,比如 ‘0’ == ‘1’ => false , 0 == 1 =>false , true == false =>false
- 如果类型不一样,可以都转成number来判断,ture => 1, false => 0 ,注意null和undefined例外,后面讲
- 注意字符串转number的时候,普通的数字字符串就直接是数字,‘0’ => 0, ‘’ =>0(空字符串为0),其他字符串就是NaN, ‘string’ =>NaN , ‘true’ =>NaN ,但是有意义的转义符不为NaN,比如回车、换行,’\r’ 和’\n’ 都是转为 0
- 在关系运算符中,null,undefined会被Number()强制转换成数字类型;
在相等运算符中,null,undefined则不会转化为数字类型,而是经过特殊处理后转化为false(当然,除了与自身对比,或者是null与undefined对比,即都为true)。
//关系运算符下
null >= 0 //true
undefined >= 0 //false
//相等运算符下
null == 0 //false
undefined == 0 //false
null == undefined //true
null == null //true
undefined == undefined //true
null == 0 //false
undefined == 0 //false
有个坑
这个if判断是能进入的
if('0'){
xxx
}
但是
'0' == false
得到的是true
因为==的操作会把两边变成number
'0' => 0
false => 0
所以就相等了,但是单看字符串 '0' 是true的,字符串只有 '' 是false
// 小坑
"0" == false // -> true 这里false先被转为0,"0"也会转为0,所以为true
"0" == "" // -> false 两个都是字符串类型,直接比较
0 == '' // -> true 空字符串直接转为0
false == [] // -> true false先转为0;[]空数组转为'',之后ToNumber操作转为0
// 大坑
[] == ![] // -> true [] 这里![]先被强制转换为false,变成[]与fasle的比较,之后fasle->0;[]->''->0,所以为true。
2=[2] // -> true [2]->'2'->2 所以为true
''==[null] // true [null]->''
0=='\n' // -> true '\n'->''->0
'true'==true // -> false true->1;'true'->NaN,所以为false
举例并解释
{} == [] 和 {} == ![]
报错,把{}当做代码块了
{} == {} 和 [] == []
false
解释为两个都是引用地址,所以不同
{} == !{}
左边转为 "[object Object]"
右边转为 false
都是简单类型,继续转为 NaN 和 0
所以最后为false
[] == []
false
引用地址不用
[] == ![]
true
左边转为 ''
右边作为 false
左边继续转为 '' => false => 0 ,右边false => 0
所以0 == 0 , 返回true
[] == {}
false
左边 ''
右边 "[object Object]"
所以false
[] == !{}
true
左边 ''
右边 false
继续 左边 '' => false => 0 ,右边false => 0
所以0 == 0 , 返回true
下面是结合别人的之前的总结,有点乱
对于经常见到的面试题来说,两个数或者对象啥的相加,判断其结果
比如
1 + 1
1 + false
1 + {}
[] + {}
{} + []
总结其规律,参考
-
当 两个操作数都是数值 时,执行常规的数值加法计算。但有几个值的考虑
如果有一个操作数是NaN, 则结果是NaN;
Infinity 加 Infinity 结果是 Infinity;
-Infinity 加 -Infinity 结果是 -Infinity;
Infinity 加 -Infinity 结果是NaN;
+0 加 +0 结果是+0;
-0 加 -0 结果是 -0;
+0 加 -0 结果是+0; -
一般非基础类型进行转换时会先调用 valueOf,如果 valueOf 无法返回基本类型值,就会调用 toString
-
当有 一个操作数是字符串 时,应用如下规则:
如果两个操作数都是字符串,则将两个字符串拼接起来;
如果只有一个操作符是字符串,则两另一个操作符转换为字符串(toString),然后再将两个字符串拼接起来。 -
当 有一个操作数是复杂数据类型(对象,数组) 时,将两个操作数都转换为字符串(ToString)相加。比如 []+{}
-
当 有一个操作数是简单数据类型(true/false, null,undefined) 时,同时不存在复杂数据类型和字符串,则将两个操作数都转换成数值 Number(xx) 相加。1 + false
-
另外还有一种特殊情况{} + 头 的相加式,有些浏览器会将{}视为一个块符号,所以不会参与相加,而是把+符号视为转换符(Number)将后面的操作数转换为数值。
-
Number( ture ) = 1
-
Number( false ) = Number( null ) = Number( [ ] ) = 0
-
Number( undefined ) = Number( { } ) = NaN
[] + {}
可以看成
[].toString() + Object.prototype.toString.apply({})
因为{}无法直接调用toString,{}会被当成代码块
变成
'' + "[object Object]" = "[object Object]"
{} + []
+ []
Number([]) => Number("") => 0
{} + {}
+ {}
Number({}) => Number("[object Object]") => NaN
但是chrome里面是输出的 "[object Object][object Object]"
不同浏览器不一样
[] + []
'' + '' = ''
1 + {}
'1' + "[object Object]" = "1[object Object]"
1 + false
1 + 0 = 1
'1' + false
'1' + 'false' = '1false'