true + false12 / "6""number" + 15 + 315 + 3 + "number"[1] > null"foo" + + "bar""true" == truefalse == "false"null == ""!!"false" == !!"true"["x"] == "x"[] + null + 10 || "0" && {}[1,2,3] == [1,2,3]{} + [] + {} + [1]! + [] + [] + ![]new Date(0) - 0new Date(0) + 0
答案解析
接下来我们按照之前的转换逻辑来解释一下每一道题,看一下是否和你的答案一样。
true + false // 1
‘+’ 运算符会触发 number 类型转换对于 true 和 false
12 / '6' // 2
算数运算符会把字符串 ‘6’ 转为 number 类型
"number" + 15 + 3 // "number153"
‘+’ 运算符按从左到右的顺序的执行,所以优先执行 “number” + 15, 把 15 转为 string 类型,得到 “number15” 然后同理执行 “number15” + 3
15 + 3 + "number" // "18number"
15 + 3 先执行,运算符两边都是 number 类型 ,不用转换,然后执行 18 + “number” 最终得到 “18number”
[1] > null // true==> '1' > 0==> 1 > 0==> true复制代码
比较运算符 > 执行 number 类型隐式转换。
"foo" + + "bar" // "fooNaN"==> "foo" + (+"bar")==> "foo" + NaN==> "fooNaN"复制代码
一元 + 运算符比二元 + 运算符具有更高的优先级。所以 + bar表达式先求值。一元加号执行字符串“bar” 的 number 类型转换。因为字符串不代表一个有效的数字,所以结果是NaN。在第二步中,计算表达式’foo’ + NaN。
'true' == true // false==> NaN == 1==> false'false' == false // false==> NaN == 0==> false复制代码
== 运算符执行 number 类型转换,’true’ 转换为 NaN, boolean 类型 true 转换为 1
null == '' // false复制代码
null 不等于任何值除了 null 和 undefined
!!"false" == !!"true" // true==> true == true==> true复制代码
!! 运算符将字符串 ‘true’ 和 ‘false’ 转为 boolean 类型 true, 因为不是空字符串,然后两边都是 boolean 型不在执行隐式转换操作。
['x'] == 'x' // true复制代码
== 运算符对数组类型执行 number 转换,先调用对象的 valueOf() 方法,结果是数组本身,不是原始类型值,所以执行对象的 toString() 方法,得到字符串 ‘x’
[] + null + 1 // 'null1'==> '' + null + 1==> 'null' + 1==> 'null1'复制代码
‘+’ 运算符执行 number 类型转换,先调用对象的 valueOf() 方法,结果是数组本身,不是原始类型值,所以执行对象的 toString() 方法,得到字符串 ‘’, 接下来执行表达式 ‘’ + null + 1。
0 || "0" && {} // {}==> (0 || '0') && {}==> (false || true) && {}==> true && {}==> {}复制代码
逻辑运算符 || 和 && 将值转为 boolean 型,但是会返回原始值(不是 boolean)。
[1,2,3] == [1,2,3] // false复制代码
当运算符两边类型相同时,不会执行类型转换,两个数组的内存地址不一样,所以返回 false
{} + [] + {} + [1] // '0[object Object]1'==> +[] + {} + [1]==> 0 + {} + [1]==> 0 + '[object Object]' + '1'==> '0[object Object]1'复制代码
所有的操作数都不是原始类型,所以会按照从左到右的顺序执行 number 类型的隐式转换, object 和 array 类型的 valueOf() 方法返回它们本身,所以直接忽略,执行 toString() 方法。 这里的技巧是,第一个 {} 不被视为 object,而是块声明语句,因此它被忽略。计算从 +[] 表达式开始,该表达式通过toString()方法转换为空字符串,然后转换为0。
! + [] + [] + ![] // 'truefalse'==> !(+[]) + [] + (![])==> !0 + [] + false==> true + [] + false==> true + '' + false==> 'truefalse'复制代码
一元运算符优先执行,+[] 转为 number 类型 0,![] 转为 boolean 型 false。
new Date(0) - 0 // 0==> 0 - 0==> 0复制代码
‘-‘ 运算符执行 number 类型隐式转换对于 Date 型的值,Date.valueOf() 返回到毫秒的时间戳。
new Date(0) + 0==> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)' + 0==> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0'
‘+’ 运算符触发默认转换,因此使用 toString() 方法,而不是 valueOf()。
