[TOC]

数据类型转换

1. 概述

JavaScript是一种动态类型语言,变量没有类型限制,可以随时赋予任何值。

变量的类型无法再编译阶段确定,必须要在运行时才能知道。

虽然变量类型不确定,但各种运算符对数据类型是有要求的,如果运算符发现变量的类型与预期不符,就会自动转换类型。比如减法运算符期望左右两侧的变量是数值,如果不是就会自动将他们转换为数值:

'250' - '50'	// 200

2. 强制转换(显示转换)

主要使用Number(obj)String(obj)Boolean(obj)三个函数,手动将其他类型的变量转换为数字、字符串、布尔值。

2.1 强转数字的规则:Number(obj)

参数类型 转为数值的规则 举例
Number 不变 Number(123) => 123
String 如果可以被解析,转为相应数值,否则为NaN,空串和空白符( 空格、制表符、换页符和换行符)转为0 '123' => 123, '12ab' => NaN, '' =>0, '\n' => 0
Boolean true:1,false:0 true => 1, false => 0
undefined 转为 NaN undefined => NaN
null 转为0 null => 0
Object 转为NaN,但:包含单个数值的数组会返回对应数值 {} => NaN, [1] => 1,

Number(obj) 函数介绍:将其他类型的值转化成数字。Number函数整体转换,有一个无法转换就会返回NaN。参数(obj):待转换的值。

Number()关于对象的转换规则:

  1. 调用对象自身的valueOf方法,如果返回原始类型的值,则直接使用Number函数,结束
  2. 如果valueOf方法返回的还是对象,则调用对象的toString方法,如果返回原始类型的值,则直接使用Number函数,结束
  3. 如果toSrting方法返回的是对象,就报异常(Uncaught TypeError: 对象不能转为原始类型),结束
var obj = {
  valueOf: function () { return {}; },
  toString: function () { return {}; }
};
Number(obj) // Uncaught TypeError: Cannot convert object to primitive value

2.2 强转字符串规则:String(obj)

参数类型 返回结果 举例
Number 转为相应的字符串 String(123) => "123"
String 不变 String('abc') => "abc"
Boolean true: "true", false: "false" String(true) => "true"
undefined "undefined" String(undefined) => "undefined"
null " null" String(null) => "null"
Object {a: 1}: "[object Object]", 数组: 数组的字符串形式 String([1, 2, 3]) => "1, 2, 3"
NaN "NaN" String(NaN) => "NaN"

1、String()函数可以将任意类型的值转化成字符串。参数: 待转换的值。

String()关于对象的转换规则:

  1. 先调用对象的toString方法,如果返回原始类型的值,则调用String函数,结束
  2. 如果toString方法返回的是对象,再调用对象的valueOf方法,如果返回原始类型的值,则调用String函数,结束。
  3. 如果valueOf方法返回的是对象,就报异常(Uncaught TypeError: 对象不能转为原始类型),结束
var obj = {
  valueOf: function () { return {}; },
  toString: function () { return {}; }
};
String(obj) // Uncaught TypeError: Cannot convert object to primitive value

2、其他类型转为字符串的方法

1、"" + value

2、value.toString()

2.3 强转布尔规则:Boolean(obj)

转换结果
undefined false
null false
0(-0,+0) false
NaN false
''(空字符串) false
所有对象(包括空对象)(new Boolean(false)) true
其他 true

Boolean(obj)函数可以将任意类型的值转为布尔值。

所有对象的布尔值都是true,这是JavaScript出于性能的考虑,统一规定,如:obj1 && obj2

// 浏览器打开开发者工具, Console里面测试
Boolean(undefined)          // false
Boolean(null)               // false
Boolean(0)                  // false
Boolean(NaN)                // false
Boolean('')                 // false
Boolean({})                 // true
Boolean([])                 // true
Boolean(new Boolean(false)) // true

3. 自动类型转换(隐式转换)

自动转换是以强制转换为基础的,JavaScript会自动转换数据类型。

3.1 出现自动类型转换的情况

  • 比较运算(==!=><
  • ifwhile、三元运算符等需要布尔值地方
  • 算术运算(+-*/%
  • 一元运算符(+,-)
123 + 'abc'		// "123abc"
if ('abc') {}
+ {foo: 'bar'}
- [1, 2, 3]
'123' == 1

3.2 自动转换为布尔值

JavaScript遇到期望布尔值的时候(如ifwhile、三元运算符语句),就会将非布尔值的参数转为布尔值,系统自动调用Boolean函数。

if (!undefined) {}        // if语句会转换成布尔值
expression ? true : false // 三元表达式会转换成布尔值
!! expression             // 需要转换成布尔值

3.3 自动转换为字符串

遇到期望为字符串的地方,就会将参数转为字符串,转换规则:先将复合类型的值转为原始类型的值,再将原始类型的值转为字符串。

当字符串与其他变量做加法运算的时候,如果变量不是字符串,变量就会转为字符串。

'5' + 1              // '51'
'5' + true           // "5true"
'5' + false          // "5false"
'5' + {}             // "5[object Object]"
'5' + []             // "5"
'5' + function (){}  // "5function (){}"
'5' + undefined      // "5undefined"
'5' + null           // "5null"
var obj = { width: '100' };
obj.width + 20       // "10020"

3.4 自动转换为数值

遇到期望为数值的地方,就会将参数自动转为数值,系统自动调用Number函数。

1、除加法运算符(+)有可能把变量转为字符串,其他运算符都会把变量自动转为数值:

'5' - '2'     // 3
'5' * '2'     // 10
true - 1      // 0
false - 1     // -1
'1' - 1       // 0
'5' * []      // 0
false / '5'   // 0
'abc' - 1     // NaN
null + 1      // 1
undefined + 1 // NaN

2、一元运算符也会把运算子转成数值:

+'abc' 	// NaN
-'abc' 	// NaN
+true 	// 1
-false 	// 0

3.5 ==判断相等的转换规则

在使用==判断相等的时候,如果两个值类型相等,那么执行严格相等判断,如果类型不同,则会自动做类型转换为相同然后在执行严格相等判断。

对于a == b的比较规则:

类型 转换规则
都是原始类型的值 转换成Number再进行比较
对象与原始类型的值 对象转化成原始类型的值,再进行比较。
undefined 和 null 与其他类型的值比较时,结果都为false,它们互相比较时结果为true
对象与对象 比较的是对象的引用地址,两个不同对象永远不会相等
存在NaN 返回false
1 == true          // true  等同于 1 === Number(true)
2 == true          // false 等同于 2 === Number(true)
'true' == true 	   // false 等同于 Number('true') === Number(true) => NaN === 1
'' == 0            // true  等同于 Number('') === 0
'' == false        // true  等同于 Number('') === Number(false)
'\n  123  \t' == 123 // true
[1] == 1           // true  等同于 Number([1]) == 1
[1] == '1'         // true  等同于 Number([1]) == Number('1')
[1] == true        // true  等同于 Number([1]) == Number(true)
false == undefined // false 
0 == undefined     // false
undefined == null  // true
var a = {}, b = {}, c = b
a == b             // false
c == b             // true
NaN == 1           // false
NaN == NaN         // false

使用==判断会带来一些违反直觉的结果,所以一些JS规范会强制使用===来做判断。

0 == '0'            // true
0 == ''             // true

2 == true          // false
2 == false         // false

false == 'false'   // false
false == '0'       // true

false == undefined // false
false == null      // false
null == undefined  // true

' \t\r\n ' == 0    // true

详细:相等运算符 阮一峰

4. 强制转为数字的其他方法:parseInt()、parseFloat()

Number函数整体转换,parseInt和parseFloat则是逐个解析字符。

4.1 parseInt(string, radix)

parseInt(string, radix) :函数将其第一个参数转换为一个字符串,对该字符串进行解析,然后返回指定基数的十进制整数或 NaNradix 是2-36之间的整数,表示被解析字符串的基数。第二个参数可不传,默认值为10,即默认是十进制转十进制。

参数:

string:要被解析的值。如果参数不是一个字符串,则将其转换为字符串 (使用 ToString抽象操作)。字符串开头的空白符将会被忽略。 radix:从2到36之间的整数值,表示进制的基数。例如指定 16 表示被解析值是十六进制数。如果超出这个范围,将返回 NaN

关于radix参数:

若传递的是0、NaN、undefined,则分两种情况: 1、若string以“0x”或“0X”开头,则默认为16进制 2、若不是第一种情况则会10进制

若进制小于2或者大于36,就会输出NaN

若是2-36,而string是无效数字,则转为NaN

转换结果:

  • 如果输入的参数无法转化为数值类型,则返回NaN, 空字符串也返回NaN。
  • 字符串的开头的空白字符会被忽略,直到找到第一个非空白字符开始转换。
  • 从第一个字符开始,直到遇到非数字字符或结尾结束,返回解析的整数部分,非数字部分忽略。
  • 如果设置了第二个参数,表示被解析的值的进制(二进制、十进制、十六进制),返回该值对应的十进制数。
parseInt(" \n132.44ddd");  // 132
parseInt("0xF", 16);       // 15
parseInt("0xF");           // 15:默认返回十进制的解析
parseInt('')// NaN
parseInt("546", 2);        // Nan , 除了“0、1”外,其它数字都不是有效二进制数字
arseInt(" \nddd");         // NaN

4.2 parseFloat(string)

介绍:把字符串解析为浮点数并返回,parseFloat是个全局函数,不属于任何对象.

参数:

String:需要解析的字符串

转换结果:

  • 如果参数不能解析成数字,则返回NaN,parseFloat只能返回十进制数
  • 如果遇到了与浮点数无关的字符,则函数停止解析,返回已经解析到的浮点数,
  • 字符串的头部空白字符会被忽略
  • 如果字符串没有小数点或小数点后都是零,则返回整数,字符串中第一个出现的小数点是有效的。第二小数点则被解析成非数字。
  • 与浮点数相关的字符:正负号(+或-),数字(0-9),小数点,或者科学记数法中的指数(e或E)
parseFloat('');               // NaN
parseFloat('\n  32.14dsad');  // 32.14
parseFloat('  123.00000dad'); // 123
parseFloat("0.0314E+2");      // 3.14
parseFloat('  \n .12345');    // 0.12345
parseFloat('  \n .12.345');   // 0.12
rseFloat('dsss')              // NaN

参考资料

Number() MDN

parseInt() MDN

parseFloat() MDN

JavaScript 中 Number()、parseInt()、parseFloat()的区别

数据类型转换 阮一峰

运算符 阮一峰

Last Updated: 8/14/2024, 10:08:54 PM