Fork me on GitHub

强制类型转换

在js里面声明变量时并没有直接定义该变量是什么类型,变量的类型由为他赋值时所定义的值所决定(var num = 123,定义了该变量为数字)。

但是有这么一种情况,当我们需要的变量是一个数字类型,但用户输入时给定的却是一个字符串。除了给用户提示输入正确的数据类型外,是否可以从前端的角度做一些关于数据类型的处理?

这就出现了数据类型的转换。当一个变量从某种类型转化为另外一种类型时,则可以调用对应变量类型的方法。

强制类型转换

针对js中的数据类型原始值(number,string,boolean,undefined,null)和引用值(array,object,function),当不同的数据类型调用不同的方法时,看其相应的返回值。

Number()

该方法会把任意类型的数据转换为数字类型。

数字类型包括四个值:具体的数字,NaN,Infinity,-Infinity

1
2
3
4
5
6
7
Number(123.0)   //123
Number(0.300) //0.3
Number(030) //30
Number(0/0) //NaN
Number(1/0) //Infinity
Number(-1/0) //-Infinity
Number(6/2) //3

当输入具体数据时,直接输出数据。但是会对数据做以下处理:
(1)如果数字的最高位为0,删除最高位的0,返回有效的数据
(2)如果小数点后面有0,删除小数点后面无效的0
(3)如果输入的数据需要计算,则返回最后的计算结果

1
2
3
Number('123')           //123
Number('abc') //NaN
Number('123abc') //NaN

当输入字符串时,会出现3种情况:
(1)输入的字符串为纯数字,则返回具体数字
(2)输入的字符串为纯字符,则直接返回NaN
(3)输入的字符串同时包含数字和字符,返回NaN

1
2
Number(true)        //1
Number(false) //0

当输入布尔值时,true => 1,false => 0

1
2
Number(undefined)       //NaN
Number(null) //0

需要注意的是,输入null时返回的是0

1
2
3
Number({a:1,b:2,c:{d:1}})   //NaN
Number([1,2,3]) //NaN
Number([1]) //1

输入引用类型的数据时,返回的值为NaN。

但有一种特殊的情况就是当要转换的变量为数组,切数组的长度为1时,该数据类型可以直接转换为相应的数据

parseInt()

该方法趋向于将字符串转换为数字类型。

1
2
parseInt(112)        //112
parseInt(112.14) //112

输入数字时,该方法会有截取的功能,截取数字的整数部分。

即可以调用该方法将数字直接转化为整型数字(没有小数)

1
2
3
parseInt('112')     //112
parseInt('112px') //112
parseInt('abc') //NaN

当输入字符串时,会出现3种情况:
(1)输入的字符串为纯数字,则返回具体数字
(2)输入的字符串为纯字符,则直接返回NaN
(3)输入的字符串同时包含数字和字符,该方法会有截取的效果。则从第一个字符串开始,到非数字位截止。返回截取的数字部分

1
2
3
4
5
6
7
parseInt(true)          //NaN
parseInt(undefined) //NaN
parseInt(null) //NaN
parseInt({a:1}) //NaN
parseInt({1:1}) //NaN
parseInt([1]) //1
parseInt([1,2]) //1

当变量类型为引用值时,直接返回NaN。但需要注意的是,当定义的数组为第一位为数字时,返回该数组的第一位。

该方法的关键在于,趋向于将字符串转换为数字。当定义的变量不是字符串时,通常返回NaN(数字直接返回截取后的值。数组第一位为数字时,直接返回数组第一位)

该方法还可以传第二个参数,parseInt(num, radix)表示num是radix进制的数据,以radix为基底将num转换为十进制的数字。

1
parseInt('123a', 16)    //4666

该例子表示将16进制(包括0-9, a-f)的123a转换成十进制对应的数据

1
2
parseInt('112', 2)      //3
parseInt('121', 2) //1

当要转换的数据超出了该进制所包含的值时,会从超出进制的数据位对该数据进行截取,再对截取后的数据调用该方法进行转换。

将’112’的二进制转换为十进制的数据时,因为二进制只能包括0和1,所以会对’112’进行截取,截取后的数据为’11’,再将’11’转化为十进制

parseFloat()

将字符串转换为数字类型,parseInt()不同的是:
(1)可以在parseInt()的基础上保留一个小数点,即可以将数据转化为浮点型(含有小数)并去除无效的0
(2)没有第二个参数,即没有进制间的转换

1
2
parseFloat('123.020')       //123.02
parseFloat('123.020.21') //123.02

以上三个方法都是将变量转换为数字。

Boolean()

将变量转换为布尔值(0或1)

1
2
Boolean(123)    //true
Boolean("") //false

转换成布尔值为false的有:NaN, 0, “”, false, undefined, null

其他值转换为布尔值均为true

String()

将变量转化为字符串

1
2
3
4
String(123)         //"123"
String(true) //"true"
String(undefined) //"undefined"
String(null) //"null"

将任意类型直接转换为字符串,即相当于num + “”

toString()

将变量转化为字符串,除undefined, null(没有原型)

1
2.toString()    //error

这里趋向于变量调用该方法进行转换,数字直接调用时会报错。

如果传入的数据为数字类型时,应该采用如下方式处理:

1
var num = 3;num.toString()      //"3"

1
2
var num = 070; num.toString()   //56
var num=0110;num.toString() //"72"

当数字第一位为0时,会被默认为八进制,然后将其转换为十进制。即将八进制的070转换为十进制

再看以下例子:

1
2
3
3.toString()        //error
3..toString() //"3"
3...toString() //error, Unexpected token .

3..toString()中,3..相当于3.0来调用toString()的方法进行转换。

换句话说就是,如果数字直接调用toString()方法时,只有数字类型为小数(浮点型)才不会报错。否则都应该以变量声明的形式来调用。

1
2
3
3.1.toString()      //"3.1"
3.0.toString() //"3"
3.900.toString() //"3.9"

该方法可以去除小数点后面无效的0

再看其他类型的数据调用该方法时:

1
2
3
4
true.toString()             //"true"
undefined.toString() //err
[1,2].toString() //"1,2"
{a: 1, b: 2}.toString() //err

通过以上例子我们发现,当数组调用toString()方法时,会将数组直接转换为字符串。

但以上数组的组成均为数字,如果数组中含有其他类型的变量时,是否依然成立呢?

1
2
3
[1, 2, 'a', 'b', 8].toString()          //"1,2,a,b,8"
[1, [4, 'a'], {b : 1}, 'c'].toString() //"1,4,a,[object Object],c"
[1, undefined, 'b', null].toString() //"1,,b,"

首先,null, undefined是不能调用toString()方法的,直接调用时报错。在数组中调用时,数组对应的位置为空。

对象调用toString()方法也直接报错,在数组中时,返回该数据的类型[object Object]。

该方法还可以传第二个参数,variable.toString(k)表示将十进制的variable转换为k进制的数据,即将十进制转换为k进制

1
var num = 123; num.toString(16)     //"7b"

再看以下例子:将二进制10101010转换为16进制的数据

分析题目并结合以上知识点可以想到,先将二进制的数据转换为十进制,再将十进制转化为十六进制

1
2
3
4
var num2 = 10101010;
var num10 = parseInt(num2, 2);
var num16 = num10.toString(16);
console.log(num16); //"aa"