JavaScript一共包含string,number,undefined, null, boolean, object, symbol,一共7种数据类型。本文主要记录各种数据类型之间相互转换的原理。
Object与基础类型之间的转换
在聊这个问题之前,先来看几道很绕的问题吧
1,{} + ''
2, {} + 0
3, [] + []
4, [] + {}
5, {} + []
6, {} + {}
有没有觉得一脸懵逼?先在控制台打印一下结果吧
介绍原理之前,我们先做一个小实验
如图所示,声明一个对象,改写对象的valueOf和toString方法。可以看出,不论是将对象转换成字符串之后执行加法运算还是转换成字符串之后进行字符串拼接,obj都是先调用了valueOf方法,再调用toString方法,然后报错。
从这里我们可以看出js在处理对象为基础类型值时,首先调用valueOf方法,这个方法默认返回对象自身,如果能得到一个基础类型的值就返回该值;如果得到的值依然是引用类型,就会继续调用toString方法,默认返回"[object Object]",如果能得到一个基础类型的值,就返回该值,如果依然得到一个引用类型的值,则报错。这就是对象转换成基础类型值的流程。
现在看回之前的问题
1, {} + ''
根据前面的解释,第一眼是不是觉得应该返回“[object Object]”?没错,但是浏览器没有按照套路来,浏览器把前面{}当作代码块处理了。所以这一题实际上相当于+'',对''执行单目运算,将''转换成数字。从下图可以看出,这里相当于直接调用了Number方法,得到0
为什么说前面的{}是被当做代码块处理了呢,因为如果我们给{} 加一个(),让它成为一个表达式,那么就会出现我们预想中的情况了。
2, {} + 0
与第一题的情况相同,{}被当作代码块处理,相当于直接对0进行单目运算,结果为0
3,[] + []
在js中[]也是一个object,所以执行加法运算前会先执行valueOf方法,得到[],仍然是引用类型;接着执行toString,得到'',这是一个基础类型的值。两个空字符串拼接,得到空字符串。
4,[] + {}
由前面的分析指导,这里相当于直接执行'' + '[object Object]'结果显而易见
5,{} + []
这一题里面,前面的{}依然会被当做代码块执行,+''相当于Number(''),结果为0
6,{} + {}
这一题就比较抓狂了。我们先来分析一下,第一个{}会被当作代码块执行,然后执行 +'[object Object]',相当于Number('[object Object]'),得到NaN
这里你咋又不当代码块处理啦?!!!
在Firefox又执行了一遍,得到了预期的结果。看来是浏览器的锅,那就不纠结了。
总结一下:js对象转换为基础类型的值,过程为,先执行valueOf方法,默认返回对象自身;如果得到一个基础类型的值,返回该值;如果得到一个引用类型的值,执行toString方法;如果得到了基础类型的值,返回该值,如果仍没得到,报错。
That's all, thanks a lot