我们都知道,JavaScript是弱类型语言,在声明一个变量时,我们无法明确声明其类型,变量的类型根据其实际值来决定,而且在运行期间,我们可以随时改变这个变量的值和类型,另外,变量在运行期间参与运算时,在不同的运算环境中,也会进行相应的自动类型转换。
类型转换的分类
js的类型转换只有三种类型的转换: to string, to boolean, to number, 即原始数据类型{string, number, boolean, undefined, null} + 引用数据类型{object} —to→ {string, boolean, number}的类型转换。
而在这三种类型转换当中, 分为两大块:显式类型转换和隐式类型转换。
注:显式类型转换是隐式类型转换的基础,隐式类型转换就是在操作符的作用下进行显式类型转换。
一、显式类型转换
1.1.将其他类型转化成数值
1.1.1 Number函数
转换情况:
(1)字符串-->数字
如果字符串是一个合法的数字,则直接转换为对应的数字。
如果字符串是一个非法的数字,则转换为NaN。
如果是一个空串或纯空格的字符串,则转换为0。
(2)布尔-->数字
true转换为1。
false转换为0。
(3)空值-->数字
null转换为0。
(4)未定义-->数字
undefined转换为NaN。
实践一下:
// 数值: 转换后还是原来的值
Number(123); //123
// undefined:转成 NaN
Number(undefined) // NaN
// null:转成0
Number(null) // 0
// 布尔值:true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0
// 字符串:如果可以被解析为数值,则转换为相应的数值
Number('123') // 324
// 字符串:如果不可以被解析为数值,返回 NaN
Number('123abc') // NaN
// 空字符串转为0
Number('') // 0
// 对象:通常转换成NaN(除了只包含单个数值的数组)
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
1.1.2 parseInt函数
将一个字符串中的有效的整数位提取出来,并转换为Number。
var str = '123.45px';
parseInt(str); //123;
//如果需要,也可以在parseInt()中加第二个参数,表示进制
1.1.3 parseFloat函数
将一个字符串中的有效的小数位提取出来,并转换为Number。
var str = '123.45px';
parseFloat(str); //123.45;
parseInt()函数和parseFloat()函数就是专门用来将一个字符串转换为数字的。注意:如果对 非 String 的类型使用 parseInt()或 parseFloat() 则会先把它转换为String,然后再操作。
1.2.将其他类型转化为字符串
1.2.1 string函数
对于Number Boolean,String都会调用他们的toString()方法来将其转换为字符串,对于null值,直接转换为字符串"null"。对于undefined直接转换为字符串"undefined"。
实践一下:
//字符串:转换后还是原来的值
String("a") // "a"
//undefined:转为字符串"undefined"
String(undefined) // "undefined"
//null:转为字符串"null"
String(null) // "null"
//布尔值:true转为字符串"true",false转为字符串"false"
String(true) // "true"
// 数值:转为相应的字符串
String(1) // "1"
//对象
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
1.2.2 toString函数
该方法不会影响到原变量,会将转换的结果返回。
注意:Null 和 Undefined 没有 toString() 方法,如果调用他们的方法会报错。
//null和undefinde,调用toString,会报类型错误
null.toString(); //TypeError
undefined.toString(); //TypeError
1.3.将其他类型转化为布尔
1.3.1 Boolean函数
转换情况
(1)字符串 --> 布尔:除了空串其余全是true。
(2)数值 --> 布尔:除了0和NaN其余的全是true。
(3)null、undefined--> 布尔:都是false。
(4)对象 -->布尔:都是true。
//字符串:只有空串是false
Boolean('') // false
Boolean(' ') //true
//数值:0,0.0和NaN是false
Boolean(0) // false
Boolean(0.0) // false
Boolean(NaN) // false
//空值:返回false
Boolean(undefined) // false
Boolean(null) // false
//对象:都是true
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
二、隐式类型转换机制
在隐式转换中,可能最大的疑惑是:什么时候发生隐式转换,转换成什么类型?我们来看一看。
2.1.自动转换为数值类型
除了+有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。
//如果操作值之一不是数值,则被隐式调用Number()函数进行转换。
'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.2.自动转换为字符串类型
+运算中,一旦存在字符串,则会进行字符串拼接操作。
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
2.3.自动转换为布尔类型
2.3.1比较运算(==、!=、 >、<),if、while都会自动转换为布尔类型。
转换规则参照:Boolean函数。
if(undefined){ // undefined会转化为boolean中的false
console.log('真')
}else{
console.log('假') //'假'
}
接下来我们重点说一下比较运算。
2.3.2 比较运算符操作规则:
(1)如果两个操作值都是数值,则进行数值比较。
(2)如果两个操作值都是字符串,则比较字符串对应的字符编码值。
(3)如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较。
(4)NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。
(5)null与undefined是相等的。
注:null或undefined在与其他数据类型进行比较返回false。
10 >= 8 //true
'10'>= '8' //false
'10'>= 8 //true
NaN == NaN //false
null == undefined //true
undefined == 0 //false
总结
JavaScript这门语言饱受诟病的点之一就是类型转换, 有时候js的类型转换机制确实会让新手摸不着头脑。希望看完这篇文章能让刚入门的或js没有形成体系的同学有一个了解。
大家可以记住:显式类型转换是隐式类型转换的基础,隐式类型转换就是在操作符的作用下进行显式类型转换。