隐式类型转换

前言#
众所周知 javascript 是一种弱类型语言。强类型和弱类型主要是在变量类型处理的角度进行分类的。强类型是一旦指定数据类型,如果不经过强制转换,那么将永远是指定的这个类型。js 中无法声明数据类型,变量类型是根据实际值决定的,由编译器自动调用转换函数进行转换,这种方式称之为隐式转换,今天我们就来聊聊数据类型是如何隐式转换的吧!
小试牛刀#
可能很多小伙伴都知道 JS隐式转换 ,但你是否真的懂它了呢?下面来试试吧!!
定义一个变量
a,使得下面的表达式结果为true
相信很多小伙伴都懵了,还能这样?别急,我们再来看看其他的!
这下好了,彻底懵了!!下面让我们来探讨一下呗~~
javascript隐式转换规则#
隐式类型转换是在一定场景下,js 运行环境自动调用这几个方法,尝试转换成期望的数据类型
- ToString
- ToNumber
- ToBoolean
- ToPrimitive
ToString#
这里所说的
ToString可不是对象的toString方法,而是指其他类型的值转换为字符串类型的操作
- null:转为
"null" - undefined:转为
"undefined" - 布尔类型:
true和false分别被转为"true"和"false" - 数字类型:转为数字的字符串形式,如
10转为"10",1e21转为"1e+21" - 数组:相当于调用数组的
Array.prototype.join()方法,如[1, 2, 3]转为"1,2,3",空数组[]转为''空字符串,数组中的null或undefined,会被当做''空字符串处理 - 普通对象:相当于直接使用
Object.prototype.toString(),返回"[object Object]"
ToNumber#
ToNumber指其他类型转换为数字类型的操作
null: 转为 0
undefined:转为 NaN
字符串:如果是纯数字形式,则转为对应的数字,空字符转为 0 , 否则一律按转换失败处理,转为 NaN
布尔型:true 和 false 被转为 1 和 0
数组:数组首先会被转为原始类型,也就是 ToPrimitive,然后在根据转换后的原始类型按照上面的规则处理,关于 ToPrimitive,会在下文中讲到
对象:同数组的处理
ToBoolean#
ToBoolean指其他类型转换为布尔类型的操作
js 中的假值只有 false、null、undefined、''空字符、0 和 NaN,其它值转为布尔型都为 true
ToPrimitive#
ToPrimitive指对象类型(如:对象、数组)转换为原始类型的操作
- 当对象类型需要被转为原始类型时,它会先查找对象的
valueOf方法,如果valueOf方法返回原始类型的值,则ToPrimitive的结果就是这个值 - 如果
valueOf不存在或者valueOf方法返回的不是原始类型的值,就会尝试调用对象的toString方法,也就是会遵循对象的ToString规则,然后使用toString的返回值作为ToPrimitive的结果
注意:对于不同类型的对象来说,
ToPrimitive的规则有所不同,比如Date对象会先调用toString,具体可以参考ECMA标准
如果 valueOf 和 toString 都没有返回原始类型的值,则会抛出异常
前面说过,对象类型在 ToNumber 时会先 ToPrimitive,再根据转换后的原始类型 ToNumber
Number([]), 空数组会先调用valueOf,但返回的是数组本身,不是原始类型,所以会继续调用toString,得到空字符串,相当于Number(''),所以转换后的结果为"0"- 同理,
Number(['10'])相当于Number('10'),得到结果10 - 而
Number(['10', '10']),相当于Number('10,10'),得到结果NaN obj1的valueOf方法返回原始类型100,所以ToPrimitive的结果为100obj2没有valueOf,但存在toString,并且返回一个原始类型,所以Number(obj2)结果为102obj3的toString方法返回的不是一个原始类型,无法ToPrimitive,所以会抛出错误
运算符中的隐式类型转换#
下面只介绍常用的几种:
- 算术运算符
+ - 关系运算符
==
算术运算符 +#
一元 +#
二元 +#
二元加法运算符 + 可以对两个数字做加法,也可以做字符串连接操作,如果其中一个操作数是字符串或者隐式转换为字符串的对象,另外一个操作数将会转换为字符串,加法将进行字符串的连接操作
关系运算符 ==#
规则:
- 对于数字和字符串的抽象比较,将字符串进行
ToNumber操作后再进行比较 - 对于布尔值和其他类型的比较,将其布尔类型进行
ToNumber操作后再进行比较 - 对于对象和基础类型的比较,将对象进行
ToPrimitive操作后在进行比较 - 对象之间的比较,引用同一个对象则为
true,否则为false
下面来看几个例子:
最后#
我们看看文章开头说的那道题目的解法:
这样就完美解决啦!!
你掌握了js数据类型隐式转换的方法了吗
参考文章: