翻译:js中的神奇的类型转换
来源
这边文章主要讲的是运算符中的隐式类型转换,我只摘了下面的例子
true + false // 1
12 / "6" // 2
"number" + 15 + 3 // 'number153'
15 + 3 + "number" // '18number'
[1] > null // true
"foo" + + "bar" // 'fooNaN'
'true' == true // false
false == 'false' // false
null == '' // false
!!"false" == !!"true" // true
['x'] == 'x' // true
[] + null + 1 // 'null1'
[1,2,3] == [1,2,3] // false
0 || "0" && {} // {}
{}+[]+{}+[1] // '0[object Object]1'
!+[]+[]+![] // 'truefalse'
new Date(0) - 0 // 0
new Date(0) + 0 // 'Thu Jan 01 1970 02:00:00(EET)0'
true + false
加法运算符会触发数字转换
true + false
==> 1 + 0
==> 1
12 / “6”
除法运算符会触发字符串的数字转换
“number” + 15 + 3
加法运算符是从左到右结合,所以先执行"number" + 15
,因为第一个操作数是字符串,加法运算符对15进行字符串转换,第二步也是如此。
15 + 3 + “number”
如同上一个一样,先执行15+3
,因为都是数字,所以不需要进行类型转换。第二步中,因为一个操作数中有字符串,所以对数字进行字符串转换。
[1] > null
比较运算符会触发对操作数的数字转换
[1] > null
==> '1' > 0
==> 1 > 0
==> true
“foo” + + “bar”
右边运算符比左边运算符具有更高的优先级,因此+'bar'
表达式先执行。一元加号运算符会触发对字符串进行数字类型转换,由于字符串转换之后是一个非法的数字,结果是NaN
。第二步执行'foo' + NaN
"foo" + + "bar"
==> "foo" + (+"bar")
==> "foo" + NaN
==> "fooNaN"
‘true’ == true and false == ‘false’
==运算符会触发数字类型转换,字符串'true'
被转换成NaN
,布尔true
被转换成1
null == ‘’
==运算符通常会触发数字类型转换,但不是null
的情况,null
只能和null
和undefined
进行比较,不能和其他值进行比较。
!!”false” == !!”true”
!!运算符将这两个字符串转换成布尔值true
,因为他们不是空的字符串, ==不进行类型转换,只对布尔值的true
进行比较
[‘x’] == ‘x’
==运算符会触发对一个数组进行数组转换,数组的valueOf()
方法会返回数组自己,但是因为数组不是基本类型,velueOf
会被忽略。数组的toString()
仅仅将['x']
转换成字符串'x'
[] + null + 1
+会触发将[]
进行数字类型转换,和上一个一样进行toString
操作,会返回一个空的字符串,接下来就进行'' + null + 1
[1,2,3] == [1,2,3]
两边有同样类型,不进行类型转换,由于==检查值相等而不是引用相等,两个数组是两个不同的实例,所以结果是false
0 || “0” && {}
逻辑运算符||
、&&
会进行布尔类型转换,但是会返回原始操作数。0
是false
,'0'
是true
,{}
是true,最后返回{}
{}+[]+{}+[1]
所有的操作数都不是基本类型,所以+开始从左边的触发数字转换,数组和对象的valueOf
方法被忽略。使用后备toString
方法。这里有一个诀窍,第一个{}
不被看作对象,而是被视为块声明语句,因此它被忽略。于是开始从后面的+[]
开始进行评估,[]
的toString
返回一个空字符串,再对空字符串进行数字转换是0
{}+[]+{}+[1]
==> +[]+{}+[1]
==> 0 + {} + [1]
==> 0 + '[object Object]' + [1]
==> '0[object Object]' + [1]
==> '0[object Object]' + '1'
==> '0[object Object]1'
!+[]+[]+![]
这个可以根据运算符的优先级去解释
!+[]+[]+![]
==> (!+[]) + [] + (![])
==> !0 + [] + false
==> true + [] + false
==> true + '' + false
==> 'truefalse'
new Date(0) - 0
减号运算符会进行数字转换。Date.valueOf()
返回自Unix纪元以来的毫秒数
new Date(0) - 0
==> 0 - 0
==> 0
new Date(0) + 0
加号运算符触发默认转换。 Date
假定字符串转换为默认值,因此使用toString()
方法,而不是valueOf()
。