类型转换

通常我们遇到类型转换的问题,都是在if()、==、+运算等遇到的隐式转换问题,强制转换的就不说了。
隐式转换涉及以下几点:

  • ToString
  • ToNumber
  • ToBoolean
  • ToPrimitive

ToString

1
2
3
4
5
6
null // "null"
undefined // "undefined"
true // "true"
{a: 'hello'} // "[object Object]"
1.07e+21 // "1.07e+21"
[1,2,3] // "1,2,3"

突发奇想 function的toString

1
2
function a(){}
a.toString(); // "function a(){}"

ToNumber

1
2
3
4
5
6
7
8
null // 0
undefined // NaN
true // 1
false // 0
能够转成数字的字符串 // 对应数字
不能转成数字的字符串 // NaN
空字符串 // 0
对象需要先转成原始类型,再进行转换,该过程为ToPrimitive

ToBoolean

1
2
3
4
5
6
7
8
9
null // false
undefined // false
空字符串 // false
非空字符串 // true
0 // false
NaN // false
其他数字 // true
{} // true
[] // true

ToPrimitive

内部调用[[DefaultValue]](hint)

hint为String,先检查是否有toString()方法,有并且返回基本类型的值的话,调用该方法。否则检查是否有valueOf(),若有且返回基本类型值的话,调用valueOf()方法。

hint为Number或者default的话,与String的调用顺序相反。

若没有对valueOf和toString重写,则:

对象的valueOf()返回对象本身,toString()返回”[object Object]”

数组的valueOf()返回数组本身,toString()返回所有单元字符串化以后再用”,”连接起来

Date对象先调用toString,其他对象相反,先valueOf

转换

+ 转换

奇怪?在控制台上输入

1
2
3
{} + [] // 0
[] + {} // "[object Object][object Object]"
{} - 1 // -1

可以看到,当{}在前面时,控制台把它当成了一个代码片段?

number + 其他类型

1
2
3
4
5
1 + "1" // "11"
1 + undefined // NaN
1 + null // 1
1 + {} // "1[object Object]"
1 + [] // "1"

string + 其他类型

1
2
3
4
"1" + {} // "1[object Object]"
"1" + false // "1false"
"1" + null // "1null"
"1" + function a(){} // "1function a(){}"

boolean + 其他类型

1
2
3
4
5
true + "" // "true"
true + true // 2
true + null // 1
true + undefined // NaN
true + {} // "true[object Object]"

不得不感叹,在+二元运算里,string的基因是真的强大,只要有string类型,全都转成string了。

以上情况+是二元运算,当它是一元时

1
2
3
4
5
6
7
+true // 1
+"aa" // NaN
+"" // 0
+function(){} // NaN
+[] // 0
+[1,2,3] // NaN
+{} // NaN

其他的运算符都转为数字。
比如

1
"" - 1 // -1

== 转换

网上看到的总结

1
2
3
4
undefined == null // true 这两个值与其他值比较都为false
String == Boolean // 都转为Number
String/Boolean == Number // String/Boolean转为Number
Object == Primitive // Object调ToPrimitive转为原始值后,再比较,比较规则就上面三条对应转换。

一道面试题

(a==1 && a==2 && a==3) 为true

1
2
3
4
5
6
var a = {
num: 0,
valueOf:function(){
return ++this.num
}
}