可能发生隐式类型转换的场景以及转换原则,应如何避免或巧妙应用

文章详细介绍了JavaScript中将非数值转换为数值的Number、parseInt和parseFloat函数,以及在运算符作用下发生的隐式类型转换,特别是+和==的规则。还讨论了对象转换为原始类型的过程,包括ToPrimitive函数的逻辑,并通过示例解释了不同类型转换的实际应用。
摘要由CSDN通过智能技术生成

数值转换

有三个函数可以将非数值转换为数值:Number()、parseInt()、parseFloat()。Number()是转型函数,可用于任何数据类型。后两个函数主要用于将字符串转换为数值。

隐式类型转换

  1. 涉及类型转换最多的两个运算符是+和==。+可以是字符串相加,也可以是数字相加,在操作符中存在字符串时,优先转换为字符串。
  2. −∗/- * /−∗/ 只针对Number类型,所以转换的结果只能是Number类型。

三种转换

转换为数字

ES定义所有对象都有toString()方法,无论它是伪对象还是对象。

参数结果
string解析为数字,含有除了数字之外的字符,则转换为NAN
booleantrue->1 false->0
undefinedNAN
null+0
[]+0
[5]5
{}NAN
‘111’111 空字符串转为0 含有字符的字符串转为NaN
Symbol报错

转换为字符串

参数结果
booleantrue->‘true’ false->‘false’
undefined‘undefined’
null‘null’
Number直接转换,例如123->‘123’
[]“”
[5,2]“5.2”
{}‘[Object Object]’
Symbol‘Symbol()’

转换为布尔值

参数结果
string除了空串都是’true’
undefinedfalse
nullfalse
Number除了+0 -0 NaN之外其他都为true
[]true
{}true
Symboltrue

===的判断

  1. ===属于严格相等,直接判断两者的类型是否相同,不同则返回fals
  2. 如果相同再比较大小,不会进行任何隐式转换
  3. 对于引用类型来说,比较的都是引用内存地址,所以===这种方式的比较,除非两者存储的内存地址相同才相等,反之false

==涉及的类型转换规则

  • 两边的类型是否相同,相同的话就比较值的大小。
  • 判断是否是null和undefined,是的话就返回true。
  • 判断类型是否是String和Numner,是的话就把String类型转成Number,再比较。
  • 判断一方是否是Boolean,是的话就把Boolean转换成Number,再进行比较。
  • 如果其中一方是Object,且另一方为String、Number或者Symbol,会将Object转换成字符串,再进行比较。

[]==![]

  1. 首先将![]转为布尔值,[]->true,!true->false,false->0
  2. []->0 故0==0,返回true。

对象转原始类型是根据什么流程运行的?

对象转原始类型,会调用内置的[ToPrimitive]函数,对于该函数,其逻辑如下:

  1. 如果Symbol.toPrimitive()方法,优先调用再返回
  2. 调用valueof(),如果转换为原始类型就返回
  3. 调用toString(),如果转换为原始类型就返回
  4. 如果都没有返回原始类型,会报错

并非所有对象的隐式转换都会按照这个流程进行,Date对象会优先尝试toString方法来实现转换,非Date对象按照上述顺序。

类型valueOftoString
Object对象本身,这是默认情况返回’[object ObjectName]',其中ObjectName是对象类型的名称
String字符串值返回String对象的值
Number数字值返回数值的字符串表示、还可以返回指定进制表示的字符串
BooleanBoolean值为true,返回’true’;为false,返回’false’
Array数组本身将Array的每个元素转为字符串,并将他们依次连接起来,两个元素之间用英文逗号作为分隔符进行拼接
Date存储的时间是从1970年1月1月午夜开始计的毫秒数UTC返回日期的文本表示
Function函数本身返回如下格式的字符串,其中functionname是一个函数的名称,此函数的toString()方法被调用:“function functionname(){[native code]}”

例子

({} + {})

  1. 进行ToPrimitive转换,由于没有指定PreferredType类型,{}会使默认值为Number,进行ToPrimitive(input, Number)运算。
  2. 执行valueOf方法,({}).valueOf(),返回的还是{}对象,不是原始值。
  3. 继续执行toString方法,({}).toString(),返回"[object Object]“,是原始值。 故得到最终的结果,”[object Object]" + “[object Object]” = “[object Object] [object Object]”

2 * {}

首先*运算符只能对number类型进行运算,故第一步就是对{}进行ToNumber类型转换。

  1. 由于{}是对象类型,故先进行原始类型转换,ToPrimitive(input, Number)运算。
  2. 执行valueOf方法,({}).valueOf(),返回的还是{}对象,不是原始值。
  3. 继续执行toString方法,({}).toString(),返回"[object Object]",是原始值。
  4. 转换为原始值后再进行ToNumber运算,"[object Object]"就转换为NaN。 故最终的结果为 2 * NaN =NAN

参考:《可能发生隐式类型转换的场景以及转换原则,应如何避免或巧妙应用》

ps:文末附上汇总文章链接《一名【合格】前端工程师的自检清单【自检ing】》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值