ES5中一共有6种数据类型,其中5种基本类型(String、Number、Boolean、Null、Undefined),1种引用类型(Object)。基本类型值可以相互换转换,并且引用类型值也可以通过某种方式转换成基本类型值。
引用类型值转换为基本类型值的方法有两个,分别是 valueOf
方法和toString
方法。
强制转换为基本类型值可以使用各自的函数 String,Boolean, Number。
转换为String
类型 | 值 | strting值 |
---|---|---|
String | “a” | “a” |
Number | 1 | “1” |
Boolean | true | “true” |
Boolean | false | “false” |
Null | null | “null” |
Undefined | undefined | “undefined” |
Object | {} | {}.toString() |
普通对象Object转换为String,如果Object没有自定义toString方法则默认返回对象的[[class]]属性,如题如下:
1.自定义对象具有toString方法
var a = {toString: function(){return '我是toString的返回值';}
};
String(a); //我是toString的返回值
2.自定义对象并不具有toString方法
var a = {};
String(a); // [object Object]var b = [];
String(b); // "" 数组有自定义的toString方法 将数组元素用 , 拼接成字符串并返回
注:Number转换为String稍微有点特殊,如果数字过大或者过小则用指数表示。
转换为Number
类型 | 值 | Number值 |
---|---|---|
Number | 1 | 1 |
String | “” | 0 |
String | “1” | 1 |
String | “1a” | NaN(数字的一种,意思是Not a Number) |
Boolean | true | 1 |
Boolean | false | 0 |
Null | null | 0 |
Undefined | undefined | NaN |
Object | {} | 调用 valueOf() 或者 toString() |
对象转为Number类型步骤:
- 调用对象的 valueOf 方法(如果有该方法),检查返回值
- 如果valueOf返回值是基本类型则转为Number
- 如果valueOf返回值不是基本类型则调用toString
- 如果toString返回值是基本类型则转为Number
- 如果toString返回值也不是基本类型则报错
1.具有valueOf方法和toString方法的对象
var a = {valueOf: function(){return 1;},toString: function(){return '2';}
}
Number(a); // 1
2.只具有toString方法的对象
var a = {toString: function(){return '2';}
}
Number(a); //2 这个 2 是数字并不是字符串
3.具有返回引用类型值得valueOf方法和toString方法
var a = {valueOf: function(){return {};},toString: function(){return {};}
}
Number(a); //TypeError 错误
转换为Boolean
在JS中所有值可以分为两类真值和假值,对象(引用类型)一般都是真值。
类型 | 值 | Boolean类型 |
---|---|---|
Boolean | true | true |
Boolean | false | false |
String | “1” | true |
String | “” | false |
Number | 0 | false |
Number | 1 | true |
Number | NaN | false |
Object | {} | true |
隐式强制类型转换
在JS中有很多的隐式强制类型转换,在一些并不明显的地方发生了强制类型转换,例如加法运算符(+),减法运算符(-),逻辑运算符 && 和 ||等。
符号 + 中出现的隐式强制类型转换
加法运算符既可以用作字符串的拼接,也可以用作数字的相加。
加法运算符的两个操作数只要有一个是字符串则执行字符串的拼接,否则执行数字的相加。
var a = '1' + 1;
console.log(a); // '11'var b = 1 + 1;
console.log(2); // 2
加法运算符的两个操作数中如果有对象则遵循以下步骤:
调用 valueOf 方法,如果返回值是基本值则依据第一条继续执行相加操作
如果返回值不是基本值则调用 toString 方法,如果返回值是基本值则依据第1条继续执行相加操作
如果 toString 也不返回基本值则报错
// 1. 应该是首先调用valueOf方法,并且对于返回的基本类型值不会toNumber
var a = {valueOf: function(){return '1';},toString: function(){return 1;}
};console.log(a + 1); // '11'// 2. 如果valueOf返回的不是基本类型值则调用toString
var b = {valueOf: function(){return {};},toString: function(){return '1';}
};console.log(b + 1); // '11'// 3. 如果两个方法都不返回基本类型值则报错
var c = {valueOf: function(){return {};},toString: function(){return {};}
};console.log(c + 1); TypeError 报错了
如果操作数中有Boolean,依据另一个操作数的类型来强制类型转换
另一个操作数是String则将Boolean转换为String,依据转换为String规则
另一个操作数是Number则将Boolean转换为Number,依据转换为Number规则
var a = 1 + true;
console.log(a); // 2var b = 1 + false;
console.log(b); // 1var c = '1' + true; // '1true'
console.log(c); // '1true'var d = '1' + false;
console.log(d); // '1false'
根据以上规则经常看到的 a + ''
就不难理解了,就是要将a转换为字符串。但是要注意的是a如果是对象的话和直接调用String(a)
的结果在特定情况下还是有区别的。区别在于String方法并不会调用valueOf方法(但是正常情况下并不会自定义对象的valueOf方法)。
算术运算符中除了 + 以外的其他运算符都会将两个操作数依据转换为Number规则换为Number,然后在进行操作。
关于 [] + {} 和 {} + [] 得到结果不一样的解释
[] + {}; // 控制台中结果是 "[object Object]"{} + []; // 控制台中结果是 数字0
[]
转为基本类型值为 “” 空子符串,{}
转为基本类型值为”[object Object]”则得到结果”[object Object]”
JS中以大括号开头会被当做代码块,{} + []
解释为 +[]
则得到了0
到Boolean类型值的隐式强制类型转换
在以下语句和表达式中需要Boolean类型值的地方都会出现依据转为Boolean规则向Boolean类型值转换:
- if( … )
- for( …; …; … ) 括号中第二个表达式
- while( … ) 和 do…while( … )
- … ? … : …
- 逻辑运算符 && 和 || 的左操作数(为什么是左操作数?右边为什么没有变成Boolean类型值?)
- ! 取反
宽松等于(==)中的隐式强制类型转换
在JS中宽松等于有很多让人捉摸不透的地方例如 [] == false
返回的是true,但是 []
显然并不是假值但是却相等,[]==![]
你猜的没错这个也返回true,"0"==false
你又才对了这个返回的还是true,我想说的是”0”并不是假值但是为什么还会返回true呢???
详情请看 JS中令人捉摸不透的宽松等于
参考:
你不知道的javascript中卷