javascript是动态类型语言,也就是说变量没有类型限制,可以随时赋予任意值;所以类型是没法在编译阶段就知道的,只能在运行阶段才能知道
如果某个运算符发现,运算子的类型和预期的不符,就会自动类型转换.
javascript中类型转换包括: 强制类型转化和自动类型转换
强制类型转换
强制类型转换主要是指Number(),String()和Boolean()三个函数,手动将各种类型的值转换为数值,字符串,布尔值
Number()
Number是将任意类型的值转换为数值
Number转换原始数据类型
Number()转换字符串,如果有一个字符不能转换为数值,则返回NaN
// Number()转换空串,返回0
Number('')
// 如果字符串的每个字符都可以被转换成数值,则将字符串转换成相应的数值
Number('123')
// 如果字符串中只要有一个字符不能被转换成数值,则返回NaN
Number('123abc')
Number()转换boolean值,true返回1,false返回0
// NaN
Number(undefined);
// 0
Number(false);
Number转换对象
Number在将对象转换为数值时,将返回NaN,除了是包含一个数值的数组
// 123
Number([123]);
// NaN
Number([12,123]);
// NaN
Number({});
Number()的转换对象的规则:
- 调用对象的valueOf(),如果valueOf方法返回的是原始数据类型,则直接对该值使用Number函数;如果valueOf方法返回的是对象,则执行第二步
- 调用对象的toString(),如果toString()返回的是原始数据类型,则对该值直接使用Number();如果toString()返回的是对象,就报错
var obj = {a: 1;}
// NaN
console.log(Number(obj));
// 等同于
if(typeof obj.valueOf() == 'object'){
Number(obj.toString());
}else{
Number(obj.valueOf());
}
obj.valueOf = function(){
return 12;
}
// 返回12 证明如果valueOf方法返回基本数据类型,则不再执行后续步骤
console.log(Number(obj));
// valueOf返回的是对象
obj.valueOf = function(){
return {};
}
// toString方法返回的是基本数据类型
obj.toString = function(){
return 14;
}
// 输出14 证明如果valueOf方法返回的是对象的话,就会再次调用toString方法
console.log(Number(obj));
// valueOf和toString方法都返回对象
obj.valueOf = function(){
return {};
}
obj.toString = function(){
return {};
}
// 报错 VM2556:14 Uncaught TypeError: Cannot convert object to primitive value
console.log(Number(obj));
js中还有一个可以将字符串解析成数值的,就是parseInt
parseInt是将字符串中的从第一位开始的有效数值部分转换为数值
parseInt在转换前,会先将参数转换为字符串类型(调用toString())
借用MDN上的解释: parseInt(string,radix)将一个字符串转换为radix进制的整数,radix为介于2-36之间的数
如果 radix 是 undefined、0或未指定的,JavaScript会假定以下情况:
如果输入的 string以 "0x"或"0x"(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被解析为十六进制数。
如果输入的 string以 "0"(0)开头,radix被假定为8(八进制)或10(十进制)。具体选择哪一个radix取决于实现。
ECMAScript 5 澄清了应该使用10(十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix。
如果输入的 string 以任何其他值开头, radix 是 10 (十进制)。
如果第一个字符不能转换为数字,parseInt会返回 NaN。
// 返回123
parseInt('123abc');
// NaN
parseInt('a123bc')
parseInt和Number的区别
相同点:
- 都是将其他数据类型转换为数值类型
不同点: - Number()可以转换boolean类型的,parseInt不可以
- Number()可以将null转换为0,undefined和其他只要有一个字符不能转换为数值的都返回NaN;而parseInt方法null和undefined都返回NaN
- parseInt是将字符串中的从第一位开始有效数值部分转换为数值,否则返回NaN,而Number更严格,只要有一个字符不能转换就返回NaN
- Number会解析对象时先调用valueOf(),如果返回的是对象的话再调用toString();parseInt()直接调用toString()
String()
String()和toString()都是返回参数的字符串形式.不同的是null和undefined两个没有toString(),所以想把null和undefined转换为字符串的话必须调用String()
String()解析基本数据类型
// "null"
String(null);
// "undefined"
String(undefined);
// "123"
String(123);
// "abc"
String('abc');
// "true"
String(true);
String()解析对象
String()解析对象规则:
- 先调用对象自身的toString方法,如果返回的值是原始值类型,则直接使用String(),不再继续下面步骤
- 如果toString()返回的是对象类型,则调用valueOf(),如果valueOf()返回的是基本数据类型,则不再继续下面步骤
- 如果valueOf方法返回的是对象数据类型,则报错
var obj = {a:2};
// "[object Object]"
String(obj);
// 重写String方法的toString方法
obj.toString = function(){
return {};
}
obj.valueOf = function(){
return 233;
}
// 返回"233" 可见toString方法返回的是对象,会继续调用valueOf()
String(obj);
// 重写String方法的toString方法
obj.toString = function(){
return {};
}
obj.valueOf = function(){
return {};
}
// Uncaught TypeError: Cannot convert object to primitive value
String(obj);
Boolean
除了以下几个值返回false,其他的都返回true
- undefined
- null
- ''
- 0
- NaN
- false
自动类型转换
自动类型转换是建立在强制类型转换基础之上的
当发现实际数据和预期值类型不一样的时候,会发生自动类型转换,一般分为以下三种情况:
- 不同类型的数据互相运算
// 2 1 + true
- 对非布尔值类型的数据求布尔值
- 对非数值类型的值使用一元运算符(+或-)