JS数据类型转换完全攻略

JavaScript 能够根据运算环境自动转换值的类型,以满足运算需要。但是在很多情况下需要开发者手动转换数据类型,以控制运算过程。

转换为字符串

常用值转换为字符串,如图所示。

常用值转换为字符串
转换前 转换后
1 "1"
0 "0"
true "true"
false "false"
"" ""
undefined "undefined"
null "null"
NaN "NaN"
Infinity "Infinity"

把值转换为字符串的常用方法有 2 种,具体说明如下。

1. 使用加号运算符

当值与空字符串相加运算时,JavaScript 会自动把值转换为字符串。

1) 把数字转换为字符串,返回数字本身。
var n = 123;
n = n + "";
console.log(typeof n); //返回类型为 string

2) 把布尔值转换为字符串,返回字符串 "true" 或 "false"。
var b = true;
b = b + "";
console.log(b); //返回字符串"true"

3) 把数组转换为字符串,返回数组元素列表,以逗号分隔。如果是空数组,则返回空字符串。
var a = [1,2,3];
a = a + "";
console.log(a); //返回字符串 "1,2,3"

4) 把函数转换为字符串,返回函数的具体代码字符串。
var f = function(){return 1;};
f = f + "";
console.log(f);  //返回字符串 "function (){return 1;}"

① 如果是内置类型函数,则只返回构造函数的基本结构,省略函数的具体实现代码。而自定义类型函数与普通函数一样,返回函数的具体实现代码字符串。
d = Date + "";
console.log(d);  //返回字符串 "function Date () { [ native code ] } "

② 如果是内置静态函数,则返回 [object Class] 格式的字符串表示。
m = Math +"";
console.log(m);  //返回字符串 "[object Math]"

5) 如果把对象实例转换为字符串,则返回的字符串会根据不同类型或定义对象的方法和参数而不同。具体说明如下。

① 对象直接量,则返回字符串为 "[object object]"
var a = {
  x :1
}
a = a + "";
console.log(a);  //返回字符串 "[object object]"

② 如果是自定义类的对象实例,则返回字符串为 "[object object]"。
var a =new function(){}();
a = a + "";
console.log(a);  //返回字符串 "[object object]"

③ 如果是内置对象实例,具体返回字符串将根据参数而定。

正则表达式对象会返回匹配模式字符串,时间对象会返回当前GMT格式的时间字符串,数值对象会返回传递的参数值字符串或者0等。
a = new RegExp(/^\w$/) + "";
console.log(a);  //返回字符串 "/^\w$/"

加号运算符有两个计算功能:数值求和、字符串连接。但是字符串连接操作的优先级要大于求和运算。因此,在可能的情况下,即运算元的数据类型不一致时,加号运算符会尝试把数值运算元转换为字符串,再执行连接操作。

但是当多个加号运算符位于同一行时,这个问题就比较复杂。例如:
var a = 1 + 1 + "a";
var b= "a" + 1 + 1;
console.log(a);  //返回字符串 "2a"
console.log(b);  //返回字符串"a11"
通过上面代码可以看到,加号运算符还会考虑运算的顺序。对于变量 a 来说,按照从左到右的运算顺序,加号运算符会执行求和运算,然后再执行连接操作。但是对于变量 b 来说,由于 "a" + 1 表达式运算将根据连接操作来执行,所以返回字符串 "a1",然后再用这个字符串与数值 1 进行运算,再次执行连接操作,最后返回字符串 "a11”,而不是字符串 "a2”。

如果要避免此类现象的发生,可以考虑使用小括号运算符来改变表达式的运算顺序。
var b = "a" + (1 + 1) ; //返回字符串 "a2"

2. 使用toString()方法

当为简单的值调用 toString() 方法时,JavaScript 会自动把它们封装为对象,然后再调用 toString() 方法,获取对象的字符串表示。
var a = 123456;
a.toString();
console.log(a);  //返回字符串“123456”

使用加号运算符转换字符串,实际上也是调用 toString() 方法来完成,只不过是 JavaScript 自动调用 toString() 方法实现的。

JavaScript 能够根据运算环境自动转换变量的类型。在自动转换中,JavaScript 一般根据运算的类型环境,按需进行转换。例如,如果在执行字符串为字符串;如果在执行基本数学运算,则会尝试把字符串转换为数值;如果在逻辑运算环境中,则会尝试把值转换为布尔值等。

转换为数字模式字符串

toString() 是 Object 类型的原型方法,Number 子类继承该方法后,重写了 toString(),允许传递一个整数参数,设置显示模式。数字默认为十进制显示模式,通过设置参数可以改变数字模式。

1) 如果省略参数,则 toString() 方法会采用默认模式,直接把数字转换为数字字符串。
var a = 1.000;
var b = 0.0001;
var c = 1e-1;
console.log(a.toString());  //返回字符串“1”
console.log(b.toString());  //返回字符串“0.0001”
console.log(c.toString());  //返回字符串“0.0001”

toString() 方法能够直接输出整数和浮点数,保留小数位。小数位末尾的零会被清除。但是对于科学计数法,则会在条件许可的情况下把它转换为浮点数,否则就用科学计数法形式输出字符串。
var a = 1e-14;
console.log(a.toString());  //返回字符串“1e-14”

在默认情况下,无论数值采用什么模式表示,toString() 方法返回的都是十进制的数字字符串。因此,对于八进制、二进制或十六进制的数字,toString() 方法都会先把它们转换为十进制数值之后再输出。
var a = 010;  //八进制数值 10
var b = 0x10;  //十六进制数值10
console.log(a.toString());  //返回字符串“8”
console.log(b.toString());  //返回字符串“16”

2) 如果设置参数,则 toString() 方法会根据参数把数值转换为对应进制的值之后,再输出为字符串表示。
var a = 10;  //十进制数值 10
console.log(a.toString(2));  //返回二进制数字字符串“1010”
console.log(a.toString(8));  //返回八进制数字字符串“12”
console.log(a.toString(16));  //返回二进制数字字符串“a”

转换为小数格式字符串

使用 toString() 方法把数值转换为字符串时,无法保留小数位。这对于货币格式化、科学计数等专业领域输出显示数字来说,无疑是不方便的。为此,JavaScript 提供了 3 个专用方法,具体说明如下。

1) toFixed()

toFixed() 能够把数值转换为字符串,并显示小数点后的指定位数。
var a = 10;
console.log(a.toFixed(2));  //返回字符串“10.00”
console.log(a.toFixed(4));  //返回字符串“10.0000”

2) toExponential()

toExponential() 方法专门用来把数字转换为科学计数法形式的字符串。
var a = 123456789;
console.log(a.toExponential(2));  //返回字符串“1.23e+8”
console.log(a.toExponential(4));  //返回字符串“1.2346e+8”
toExponential() 方法的参数指定了保留的小数位数。省略部分采用四舍五入的方式进行处理。

3) toPrecision()

toPrecision() 方法与 toExponential() 方法相似,但它可以指定有效数字的位数,而不是指定小数位数。
var a = 123456789;
console.log(a.toPrecision(2));  //返回字符串“1.2e+8”
console.log(a.toPrecision(4));  //返回字符串“1.235e+8”

转换为数字

常用值转换为数字说明如下:

常用值转换为数字
1 1
0 0
true 1
false 0
"" 0
undefined NaN
null 0
NaN NaN
Infinity Infinity

把值转换为数字的常用方法有 3 种,具体说明如下。

使用 parseInt()

parseInt() 是一个全局方法,它可以把值转换为整数。转换的过程如下:
  • 先解析位置 0 处的字符,如果不是有效数字,则直接返回 NaN。
  • 如果位置 0 处的字符是数字,或者可以转换为有效数字,则继续解析位置 1 处的字符,如果不是有效数字,则直接返回位置 0 处的有效数字。
  • 以此类推,按照从左到右的顺序,逐个分析每个字符,直到发现非数字字符为止。
  • parseInt() 将把前面分析合法的数字字符全部转换为数值并返回。
console.log(parseInt("123abc"));  //返回数字123
console.log(parseInt("1.73"));   //返回数字1
console.log(parseInt(".123"));   //返回值NaN
浮点数中的点对于 parseInt() 来说属于非法字符,因此不会转换小数部分的值。

如果是以 0 开头的数字字符串,则 parseInt() 会把它作为八进制数字处理:先把它转换为八进制数值,然后再转换为十进制的数字返回。

如果是以 0x 开头的数字字符串,则 parseInt() 会把它作为十六进制数字处理:先把它转换为十六进制数值,然后再转换为十进制的数字返回。
var d = 010;  //八进制数字字符串
var e = 0x10;  //十六进制数字字符串
console.log(parseInt(d));  //返回十进制数字8
console.log(parseInt(e));  //返回十进制数字16
parseInt() 也支持基模式,可以把二进制、八进制、十六进制等不同进制的数字字符串转换为整数。基模式由 parseInt() 函数的第二个参数指定。

【实例1】下面代码把十六进制数字字符串“123abc”转换为十进制整数。
var a = "123abc";  
console.log(parseInt(a,16));  //返回十进制整数1194684

【实例2】下面代码把二进制、八进制和十进制数字字符串转换为十进制的整数。
console.log(parseInt("10",2));  //把二进制数字 10 转换为十进制整数,为 2
console.log(parseInt("10",8));  //把八进制数字 10 转换为十进制整数,为 8
console.log(parseInt("10",10));  //把十进制数字 10 转换为十进制整数,为 10

【实例3】如果第一个参数是十进制的值,包含 0 前缀,为了避免被误解为八进制的数字,则应该指定第二个参数值为 10,即显示定义基模式,而不是采用默认基模式。
console.log(parseInt("010"));  //把默认基模式数字 010 转换为十进制整数为 10
console.log(parseInt("010",8));  //把八进制数字 010 转换为十进制整数为 8
console.log(parseInt("010",10));  //把十进制数字 010 转换为十进制整数为 10

使用 parseFloat() 函数

parseFloat() 也是一个全局方法,它可以把值转换为浮点数,即它能够识别第一个出现的小数点,而第二个小数点被视为非法。解析过程与 parseInt() 方法相同。
console.log(parseFloat("1.234.5"));  //返回数值 1.234

parseFloat() 的参数必须是十进制形式的字符串,而不能使用八进制或十六进制的数字字符串。同时,对于数字前面的 0(八进制数字标识)会忽略,对于十六进制的数字将返回 0。
console.log(parseFloat("123"));  //返回数值 123
console.log(parseFloat("123abc"));  //返回数值 123
console.log(parseFloat("010"));  //返回数值 10
console.log(parseFloat("0x10"));  //返回数值 0
console.log(parseFloat("x10"));  //返回数值 NaN

使用乘号运算符

如果变量乘以 1,则变量会被 JavaScript 自动转换为数值。乘以 1 之后,结果没有发生变化,但是值的类型被转换为数值。如果值无法被缓缓为合法的数值,则返回 NaN。
var a = 1;  //数值
var b = "1";  //数字字符串
console.log(a + (b * 1));  //返回数值 2

转换为布尔值

常用值转换为布尔值说明如下:

常用值转换为布尔值
1 true
0 false
true true
false false
"" false
undefined false
null false
NaN false
Infinity true

把值转换为布尔值的常用方法有 2 种,具体说明如下。

1. 使用双重逻辑非

一个逻辑非运算符!可以把值转换为布尔值并取反,两个逻辑非运算符就可以把值转换为正确的布尔值。
console.log(!!0);  //返回false
console.log(!!1);  //返回true
console.log(!!"");  //返回false
console.log(!!NaN);  //返回false
console.log(!!null);  //返回false
console.log(!!undefined);  //返回false
console.log(!![]);  //返回true
console.log(!!{});  //返回true
console.log(!!function(){});  //返回true

2. 使用 Boolean() 函数

使用 Boolean() 函数可以强制把值转换为布尔值。
console.log(Boolean(0));  //返回false
console.log(Boolean(1));  //返回true

转换为对象

使用 new 命令调用 String,Number,Boolean 类型函数执行实例化操作,并把值“123”传进去,使用 new 运算符创建实例对象,简单值分别被封装为字符串型对象、数值型对象和布尔型对象。
var n = "123";
console.log(typeof new String(n));  //返回Object
console.log(typeof new Number(n));  //返回Object
console.log(typeof new Boolean(n));  //返回Object
console.log(Object.prototype.toString.call(new String(n)));  //返回 [object String]
console.log(Object.prototype.toString.call(new Number(n)));  //返回 [object Number]
console.log(Object.prototype.toString.call(new Boolean(n)));  //返回 [object Boolean]

转换为简单值

1. 在逻辑运算环境中

在逻辑运算环境中,所有复合型数据对象转换为布尔值都为 true。

下面代码创建 3 个不同类型的对象,然后参与逻辑与运算。因为不管其值是什么,凡事对象转换为布尔值都为 true,所以才看到不同的显示结果。
var b = new Boolean(false);  //封装false为对象
var n = new Number(0);  //封装数字0为对象
var s = new String("");  //封装空字符串对象
b && console.log(b);  //如果b为true,则显示 "false"
n && console.log(n);  //如果n为true,则显示 "0"
s && console.log(s);  //如果s为true,则显示""

2. 在数值运算环境中

在数值运算环境中,对象会尝试调用 valueOf() 方法;如果不成功,则再调用 toString() 方法,获取一个值。然后尝试把该值转换为数字,如果成功,则取用该值参与运算;如果转换失败,则取用 NaN 参与运算。

下面代码使用 Boolean 类型函数把布尔值 true 转换为布尔型对象,然后通过 b-0 数值运算,把布尔型对象转换为数字 1。
var b = new Boolean(true);  //把true封装为对象
console.log(b.valueOf());  //测试该对象的值为true
console.log(typeof(b.valueOf));  //测试值得类型为boolean
var n = b-0;  //投放到数值运算环境中
console.log(n);  //返回值为1
console.log(typeof n);  //测试类型,则为number

3. 在字符串运算环境中

在字符串运算环境中,对象会调用 toString() 方法,获取对象的字符串表示,以此作为转换的值。

4. 转换数组

数组转换为简单值时,会调用 toString() 方法,获取一个字符串表示,然后根据具体运算环境,再把该字符串转换为对应类型的简单值。
  • 如果为空数组,则转换为空字符串。
  • 如果仅包含一个元素,则取该元素值。
  • 如果包含多个元素,则转换为多个元素的值组合的字符串,并以逗号分隔。

5. 转换对象

当对象与数值进行加运算时,会尝试把对象转换为数值,然后参与求和运算。如果不能转换为有效数值,则执行字符串连接操作。
var a = new String("a");  //字符串封装为对象
var b = new Boolean(true);  //布尔值封装为对象
console.log(a+0);  //返回字符串"a0"
console.log(b+0);  //返回数值1

当对象与字符串进行加运算时,则直接转换为字符串,执行连接操作。
var a = new String(1); 
var b = new Boolean(true); 
console.log(a+"");  //返回字符串"1"
console.log(b+"");  //返回字符串"true"

当对象与数值进行比较运算时,则尝试把对象转换为数值,然后参与比较运算。如果不能转换为有效数值,则执行字符串比较运算。
var a = new String("true");  //无法转换为数值
var b = new Boolean(true);  //可以转换为数值
console.log(a>0);  //返回false,以字符串形式进行比较
console.log(b<0);  //返回true,以数值形式进行比较

当对象与字符串进行比较运算时,则直接转换为字符串,进行比较操作。

对于 Date 对象来说,加号运算符会先调用 toString() 方法进行转换。因为当加号运算符作用于 Date 对象时,一般都是字符串连接操作。当比较运算符作用于 Date 对象时,则会转换为数字,以便比较时间的先后。

6. 转换函数

函数转换为简单值时,会调用 toString() 方法,获取字符串表示(对于普通函数,则返回的是函数代码本身)。然后根据不同运算环境,再把该字符串表示转换为对应类型的值。
var f = function(){return 5; };
console.log(String(f));  //返回字符串function (){return 5; }
console.log(Number(f));  //返回NaN
console.log(Boolean(f));  //返回true

强制类型转换

JavaScript 支持使用以下函数进行强制类型转换。
  • Boolean(value):把参数值转换为布尔型值。
  • Number(value):把参数值转换为数字。
  • String(value):把参数值转换为字符串。

在下面代码中,分别调用上述 3 个函数,把参数值强制转换为新的类型值。
console.log(String(true));  //返回字符串"true"
console.log(String(0));  //返回字符串"0"
console.log(Number("1"));  //返回数值1
console.log(Number(true));  //返回数值1
console.log(Number("a"));  //返回NaN
console.log(Boolean(1));  //返回true
console.log(Boolean(""));  //返回false

注意:

1) true 被强制转换为数值 1,false 被强制转换为数值 0,而使用 parseInt() 方法转换时,都返回 NaN。
console.log(Number(true));  //返回1
console.log(Number(false));  //返回0
console.log(parseInt(true));  //返回NaN
console.log(parseInt(false));  //返回NaN
2) 当值包括至少一个字符的字符串、非 0 数字或对象时,Boolean() 强制转换后都会返回 true。
3) 如果值是空字符串、数字 0、undefined 或 null,Boolean() 强制转换后都会返回true。
4) Number() 强制转换与 parseInt() 和 parseFloat() 方法的处理方式不同,Number() 转换的是整体,而不是局部值。
console.log(Number("123abc"));  //返回NaN
console.log(Number("123abc"));  //返回数值123
5) String() 能够把 null 和 undefined 强制转换为对应字符串,而调用 toString() 方法将引发错误。
console.log(String(null));
console.log(String(undefined));
console.log(null.toString());
console.log(undefined.toString());

在 JavaScript 中,使用强制类型转换非常有用,但是应该根据具体应用场景使用,以确保正确转换值。

自动类型转换

JavaScript 能够根据具体运算环境自动转换参与运算的值得类型。下面简单介绍常用值在不同运算环境中被自动转换的值列表。

数据类型自动转换列表
值(value) 字符串操作环境 数字运算环境 逻辑运算环境 对象操作环境
undefined "undefined" NaN false Error
null "null" 0 false Error
非空字符串 不转换 字符串对应的数字值NaN true String
空字符串 不转换 0 false String
0 "0" 不转换 false Number
NaN "NaN" 不转换 false Number
Infinity "Infinity" 不转换 true Number
Number.POSITIVE_INFINITY "Infinity" 不转换 true Number
Number.NEGATIVE_INFINITY "-Infinity" 不转换 true Number
-Infinity "-Infinity" 不转换 true Number
Number.MAX_VALUE "1.7976931348623157e+308" 不转换 true Number
Number.MIN_VALUE "5e-324" 不转换 true Number
其他所有数字 "数字的字符串值" 不转换 true Number
true "true" 1 不转换 Boolean
false "false" 0 不转换 Boolean
对象 toString() valueOf() 或 toString() 或 NaN true 不转换