JS类型(二): JS 类型转换

前言

在第一篇文章中,讲解了 关于“==”时,JS做的类型转换。从第一篇文章中可以发现 == 时,基本类型都朝着数字类型转换,还是贴出上篇文章的图:

图片描述

那么JS类型转换都是按照这个模式进行转换的吗?例如null能转换成数字类型吗?如果能,会转换成多少?

   const data = 1 + null;
   data;// 1

你想到这个结果了吗?

正文

基本类型转换

下面是JS类型转换的图表:

图片描述

图表显示null转换成了0。等等。。。不是说null没有toString和valueOf的方法的吗?怎么能转换成数字呢??
图片描述

这完全不符合第一篇 == 的套路啊!

具体怎么回事呢?

问题在于JS类型转换只存在于“==”的时候吗?肯定不是!

除了==符号会产生类型转换,'+' '-' '*' '/' '>''<'等符号也会使JS发生类型转换,所以==的类型转换规则不是万能的,只适用于== 。那么应该如何记住类型转换这张表格呢?其实大部分转换规则是可以根据第一篇文章讲的==的转换规则得出正确答案的,只是有几个特殊的例子罢了。

第一篇文章讲到了 {}会转换成字符串'[object Object]',则:

图片描述

比较特殊的就是undefined null类型:
(1)在进行 == 的时候,undefined null 会尝试转换成基本类型,但是不存在toString valueOf方法,所以无论如何是转换不成基本类型的。
(2)在做字符串拼接的时候会按照表里面的转换成字符串的规则
(3)在做数值运算的时候会按照表中转换成数字的规则
最特殊的就是前言中介绍的null转换为0!

表格中{}转换成字符串类型和数值类型通常如下:

图片描述

这样就能记住这张类型转换表了。注意这张类型转换表适用于所以发生类型转换的情况哦。

Object类型转换成基本类型

ECMAScript内部有一个函数 ToPrimitive() (这个函数不能在javascript中调用), 下面是转换规则:

 ToPrimitive(input, PreferredType?)

这个可选的 PreferredType 表示最终要转换成的基本类型: 它是数字类型或者字符串类型,这取决于ToPrimitive()的结果是否可以转换成一个数字还是一个字符串。
如果PreferredType 是数字类型, 转换将遵循以下步骤:

  1. 如果输入的是基本类型,就直接返回它
  2. 如果输入的是Object
    (1)会先调用 input.valueOf()。如果结果是基本类型就返回它
    (2)如果input.valueOf()不是基本类型,就会调用input.toString(),如果结果是基本类型就返回它
    (3)如果还不能得到基本类型,就会抛出TypeError错误

如果PreferredType 是String, 第二条的(1)(2)顺序反转一下。

有个地方需要注意,如果指定了要转换的类型,则会优先调用转换的方法,例如:

 var s = { toString: function () { return '7'; } }; 
 
 String(s);// toString() => '7'
 Number(s);// valueOf() => 7

Number() 与 parseInt()/parseFloat()

1.Number(num) 会对boolean string null 类型做一些转换:

parseFloat(true); // same as parseFloat('true') => NaN
Number(true); // 1

parseFloat(null); // same as parseFloat('null') => NaN
Number(null); // 0

parseFloat(''); // NaN
Number(''); // 0

也就是说Number走的是类型转换那张表。
我们经常使用 +[number]的形式来实现Number(number)。

2.parseInt(num,radix)/parseFloat(num,radix)可以设置解析的进制radix,并且会解析出合法的部分:

 parseFloat('123.45#'); // 123.45
 Number('123.45#'); // NaN

parseFloat('\t\v\r12.34\n');

parseInt()/parseFloat()才是真正的解析数字。

3.使用parseInt()去解析数字会有问题

Don’t use parseInt() to convert a number to an integer:coercion to string is an unnecessary detour and even then, the result is not always correct.(《SpeakingJavascript》)

情况一:整数>=21bit之后会用e表示数字大小

 parseInt(1000000000000000000000.5, 10); // 1
 首先转换成字符串:
 String(1000000000000000000000.5); // '1e+21'

情况二:小数部分>=7bit会用e表示数字大小

parseInt(0.0000008, 10); // 8
String(0.0000008); // '8e-7' 

总结:
1.大多情况下优先使用Number()
2.如果确定是解析字符串,并且取里面能提取出的数字,这种情况下使用parseInt()/parseFloat()
3.非十进制解析的情况下使用parseInt()/parseFloat()

后记

猜测:

在做== 运算时:右侧世界undefined null ,永远不等于左侧的世界中的值,是因为undefined null 想转换成基本类型(和引用类型处理方式一致),但是它们没有toString valueOf方法;

这一篇undefined null 类型转换还可以看出:例如 + 运算,JS会根据实现,按照表格中的JS类型转换,{}转换成字符串[object Object],null装换成数字0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值