JS 类型转换的规则是什么?
类型转换的规则三言两语说不清,真想哇得一声哭出来~

JS中类型转换分为 强制类型转换 和 隐式类型转换 。
-
通过 Number()、parseInt()、parseFloat()、toString()、String()、Boolean(),进行强制类型转换。
-
逻辑运算符(&&、 ||、 !)、运算符(+、-、*、/)、关系操作符(>、 <、 <= 、>=)、相等运算符(==)或者 if/while 的条件,可能会进行隐式类型转换。
强制类型转换
1.Number() 将任意类型的参数转换为数值类型
规则如下:
- 如果是布尔值,true和false分别被转换为1和0
- 如果是数字,返回自身
- 如果是 null,返回 0
- 如果是 undefined,返回
NAN - 如果是字符串,遵循以下规则:
- 如果字符串中只包含数字(或者是
0X/0x开头的十六进制数字字符串,允许包含正负号),则将其转换为十进制 - 如果字符串中包含有效的浮点格式,将其转换为浮点数值
- 如果是空字符串,将其转换为0
- 如不是以上格式的字符串,均返回
NaN
- 如果字符串中只包含数字(或者是
- 如果是Symbol,抛出错误
- 如果是对象,则调用对象的
valueOf()方法,然后依据前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,再次依照前面的规则转换返回的字符串值。
部分内置对象调用默认的 valueOf 的行为:
| 对象 | 返回值 |
|---|---|
| Array | 数组本身(对象类型) |
| Boolean | 布尔值(原始类型) |
| Date | 从 UTC 1970 年 1 月 1 日午夜开始计算,到所封装的日期所经过的毫秒数 |
| Function | 函数本身(对象类型) |
| Number | 数字值(原始类型) |
| Object | 对象本身(对象类型) |
| String | 字符串值(原始类型) |
Number('0111'); //111
Number('0X11') //17
Number(null); //0
Number(''); //0
Number('1a'); //NaN
Number(-0X11);//-17
2.parseInt(param, radix)
如果第一个参数传入的是字符串类型:
- 忽略字符串前面的空格,直至找到第一个非空字符,如果是空字符串,返回NaN
- 如果第一个字符不是数字符号或者正负号,返回NaN
- 如果第一个字符是数字/正负号,则继续解析直至字符串解析完毕或者遇到一个非数字符号为止
如果第一个参数传入的Number类型:
- 数字如果是0开头,则将其当作八进制来解析(如果是一个八进制数);如果以0x开头,则将其当作十六进制来解析
如果第一个参数是 null 或者是 undefined,或者是一个对象类型:
- 返回 NaN
如果第一个参数是数组: 1. 去数组的第一个元素,按照上面的规则进行解析
如果第一个参数是Symbol类型: 1. 抛出错误
如果指定radix参数,以radix为基数进行解析
parseInt('0111'); //111
parseInt(0111); //八进制数 73
parseInt('');//NaN
parseInt('0X11'); //17
parseInt('1a') //1
parseInt('a1'); //NaN
parseInt(['10aa','aaa']);//10
parseInt([]);//NaN; parseInt(undefined);
parseFloat
规则和parseInt基本相同,接受一个Number类型或字符串,如果是字符串中,那么只有第一个小数点是有效的。
toString()
规则如下:
- 如果是Number类型,输出数字字符串
- 如果是 null 或者是 undefined,抛错
- 如果是数组,那么将数组展开输出。空数组,返回
'' - 如果是对象,返回
[object Object] - 如果是Date, 返回日期的文字表示法
- 如果是函数,输出对应的字符串(如下demo)
- 如果是Symbol,输出Symbol字符串
let arry = [];
let obj = {a:1};
let sym = Symbol(100);
let date = new Date();
let fn = function() {console.log('稳住,我们能赢!')}
let str = 'hello world';
console.log([].toString()); // ''
console.log([1, 2, 3, undefined, 5, 6].toString());//1,2,3,,5,6
console.log(arry.toString()); // 1,2,3
console.log(obj.toString()); // [object Object]
console.log(date.toString()); // Sun Apr 21 2019 16:11:39 GMT+0800 (CST)
console.log(fn.toString());// function () {console.log('稳住,我们能赢!')}
console.log(str.toString());// 'hello world'
console.log(sym.toString());// Symbol(100)
console.log(undefined.toString());// 抛错
console.log(null.toString());// 抛错
String()
String() 的转换规则与 toString() 基本一致,最大的一点不同在于 null 和 undefined,使用 String 进行转换,null 和 undefined对应的是字符串 'null' 和 'undefined'
Boolean
除了 undefined、 null、 false、 ''、 0(包括 +0,-0)、 NaN 转换出来是false,其它都是true.
隐式类型转换
&& 、|| 、 ! 、 if/while 的条件判断
需要将数据转换成 Boolean 类型,转换规则同 Boolean 强制类型转换
运算符: + - * /
+ 号操作符,不仅可以用作数字相加,还可以用作字符串拼接。
仅当 + 号两边都是数字时,进行的是加法运算。如果两边都是字符串,直接拼接,无需进行隐式类型转换。
除了上面的情况外,如果操作数是对象、数值或者布尔值,则调用toString()方法取得字符串值(toString转换规则)。对于 undefined 和 null,分别调用String()显式转换为字符串,然后再进行拼接。
console.log({}+10); //[object Object]10
console.log([1, 2, 3, undefined, 5, 6] + 10);//1,2,3,,5,610
-、*、/ 操作符针对的是运算,如果操作值之一不是数值,则被隐式调用Number()函数进行转换。如果其中有一个转换除了为NaN,结果为NaN.
关系操作符: ==、>、< 、<=、>=
> , < ,<= ,>=
- 如果两个操作值都是数值,则进行数值比较
- 如果两个操作值都是字符串,则比较字符串对应的字符编码值
- 如果有一方是Symbol类型,抛出错误
- 除了上述情况之外,都进行Number()进行类型转换,然后再进行比较。
注: NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。
console.log(10 > {});//返回false.
/**
*{}.valueOf ---> {}
*{}.toString() ---> '[object Object]' ---> NaN
*NaN 和 任何类型比大小,都返回 false
*/
相等操作符:
==
- 如果类型相同,无需进行类型转换。
- 如果其中一个操作值是 null 或者是 undefined,那么另一个操作符必须为 null 或者 undefined 时,才返回 true,否则都返回 false.
- 如果其中一个是 Symbol 类型,那么返回 false.
- 两个操作值是否为 string 和 number,就会将字符串转换为 number
- 如果一个操作值是 boolean,那么转换成 number
- 如果一个操作值为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断(调用object的valueOf/toString方法进行转换)
对象如何转换成原始数据类型
如果部署了 [Symbol.toPrimitive] 接口,那么调用此接口,若返回的不是基础数据类型,跑出错误。
如果没有部署 [Symbol.toPrimitive] 接口,那么先返回 valueOf() 的值,若返回的不是基础类型的值,再返回 toString() 的值,若返回的不是基础类型的值, 则抛出异常。
//先调用 valueOf, 后调用 toString
let obj = {
[Symbol.toPrimitive]() {
return 200;
},
valueOf() {
return 300;
},
toString() {
return 'Hello';
}
}
//如果 valueOf 返回的不是基本数据类型,则会调用 toString,
//如果 toString 返回的也不是基本数据类型,会抛出错误
console.log(obj + 200); //400
你好,请问object和symbol什么时候会相等?不是说symbol是唯一标识吗?我还以为它不等于任何其它东西