众所周知Javascript做为一种动态类型,弱类型的脚本语言其数据类型在不少时候都会发生类型转换。而这些类型转换每每都是隐式的,这让咱们在使用Js的时候会产生许多麻烦。而Js的基础数据类型的转换在此文中不过多阐述,主要记录Js对象数据类型的转换。笔者因为比较菜,如有写的不对的地方欢迎大佬在下方留言指正。面试
let a={name:123};
console.log(Number(a));
咱们先简单的声明一个对象,并用Number()对其进行强制类型转换浏览器
运行结果以下:函数
那么咱们来分析一下对象通过强制类型转换为何会变成NaN?spa
在这里就不得不提到Js对象所带有的两个方法,valueOf以及toString。code
咱们先说一下valueOf这个方法:对象
JavaScript调用valueOf
方法将对象转换为原始值。你不多须要本身调用valueOf
方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。blog
默认状况下,valueOf
方法由Object
后面的每一个对象继承。 每一个内置的核心对象都会覆盖此方法以返回适当的值。若是对象没有原始值,则valueOf
将返回对象自己。继承
JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能须要。所以,不一样类型对象的valueOf()方法的返回值和返回值类型都可能不一样。ip
以上描述源自MDN对valueOf方法的描述,下方给出不一样数据类型valueof的返回值:字符串
注意以上返回值是在你没有覆盖原有valueof的函数的状况下的返回值。
在上表中咱们能够清楚的看到,对象返回的值是对象自己,结果以下:
接下来咱们再说一下toString方法
一个对象在没有覆盖toString方法的状况下返回值应该为:
那么这两种方式和对象的强制类型转换有什么关系呢?
实际上当Number()强制类型转换Object对象时会进行以下操做:
1.先调用对象的valueOf方法
2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)
3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4.若返回值不为基础数据类型,则在该返回值的基础上继续调用toString方法
5.判断toString的返回值是否为基础数据类型
6.判断是否为基础数据类型,如果基础数据类型则进行操做3
7.若仍旧不为基础数据类型则报错
下面咱们对这些步骤进行验证:
这样看起来彷佛解释的通,那么咱们看看若是toString的返回值依旧是个对象看一下浏览器是否会报错吧:
果真当toString返回值仍旧为对象时Js报错了
那么咱们在验证一下若是第一次调用valueof的返回值就是基础数据类型会发生什么?
因此Number强制转换对象的过程即为如上7步
首先依旧先声明一个简单的对象
为了与上面的区分此次咱们建立一个对象b{name:b}
从上图咱们能够看到强制转换的结果为"[object object]"
一样的下面是解密时间:
事实上String强制转换对象的步骤与Number相似,也分为相似的7个步骤:
1.先调用对象的toString方法
2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)
3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4.若返回值不为基础数据类型,则在该返回值的基础上继续调用valueOf方法
5.判断valueOf的返回值是否为基础数据类型
6.判断是否为基础数据类型,如果基础数据类型则进行操做3
7.若仍旧不为基础数据类型则报错
String与Number的区别则在于
Number是先调用valueOf再调用toString
而String是先调用toString再调用valueof
为了方便下面会以一张图对此进行说明:
因此这就是String转换对象的原理
咱们知道在Js中用于能在判断时为false的只有5个值
1.undefined
2.null
3.‘’//空字符串
4.0
5.NaN
其余值在判断时都为true,而if判断时是使用了Boolean进行转换的
因此对象通过Boolean转换的值为true
——————————————————————————————————————————————————————————————————
因此一些有趣的面试题的答案也就有了解释:
{}+{}
{}+[]
[]+[]
[]+{}