两种转换形式:显式类型转换和隐式类型转换
三种转换结果:数字、布尔值、字符串
常见的显式类型转换有构造函数形式Number()、String()、Boolean(),和new一个实例不一样哦
const a = new Number('123'); // a === 123 is false
const b = Number('123'); // b === 123 is true
a instanceof Number; // is true
b instanceof Number; // is false
Number()
直接上规范:如果传入参数,调用底层函数ToNumber(),如果未传入参数,返回+0
而调用底层函数ToNumber()有如下结果
参数类型 | 结果 |
---|---|
Undefined | NaN |
Null | +0 |
Boolean | true返回1,false返回**+0** |
Number | 就是输入的参数了 |
String | 情况比较复杂 |
String的说明
console.log(Number("123")) // 123
console.log(Number("-123")) // -123
console.log(Number("1.2")) // 1.2
console.log(Number("000123")) // 123
console.log(Number("-000123")) // -123
console.log(Number("0x11")) // 17
console.log(Number("")) // 0
console.log(Number(" ")) // 0
console.log(Number("123 123")) // NaN
console.log(Number("foo")) // NaN
console.log(Number("100a")) // NaN
parseInt()和parseFloat()
这两个是针对字符串转数字的情况,因为用Number()转字符串的时候,复杂又不合理
parseInt()针对整数
忽略前导空格,第一个不为空的字符如果不是数字/正负号,就返回NaN;
解析后续字符直到遇到不是数字的字符,后面的字符全部忽略,返回之前的数字
parseInt(' +3') //+3
parseInt('') //空字符串,NaN
parseInt(' ') //NaN
parseInt('*12') //NaN
parseInt('123blue') //123
parseInt(2.25) //2,'.'不是数字,小数点后面都被忽略了
parseInt('0xf') //15,十六进制
parseInt('070') //70,八进制,但是ES5认为这是70
第二个参数可以指定进制
parseInt('070',8) //56
parseFloat(针对浮点数)
只解析十进制
忽略前导0和空格,第一个不为空的字符如果不是数字/正负号,就返回NaN;
解析后续字符,第一次遇到小数点有效,第二次就无效了,其他非数字字符第一次就无效,返回前面的数字
console.log(parseFloat(' +3')); //3
console.log(parseFloat(' -3')); //3
console.log(parseFloat('')); //NaN
console.log(parseFloat(' ')); //NaN
console.log(parseFloat('*12')); //NaN
console.log(parseFloat('123blue')); //123
console.log(parseFloat(2.25)); //2.25
console.log(parseFloat('2.25.4')); //2.25
console.log(parseFloat('0xf')); //0,遇到十六进制都是0
console.log(parseFloat('070')); //70
String()
还是上规范:如果传入参数就调用底层函数ToString(),否则返回空字符串
ToString()结果如下
参数类型 | 结果 |
---|---|
Undefined | "undefined" |
Null | "null" |
Boolean | true返回**“true”,false返回"false"** |
Number | 情况比较复杂 |
String | 没转换 |
Number的说明
console.log(String(NaN)); //"NaN"
console.log(String(-0)); //"0"
console.log(String(+0)); //"0"
console.log(String(-Infinity)); //"-Infinity"
console.log(String(Infinity)); //"Infinity"
console.log(String(0xf)); //"15"
console.log(String(070)); //"56"
toString()
Boolean、Number、String是基本包装类型,有toString方法
null和undefined没有toString方法,所以没法转换
转换规则和ToString是一样的
console.log((-0).toString()); //0
console.log((NaN).toString()); //'NaN'
console.log((0xf).toString()); //'15'
console.log((070).toString()); //'56'
console.log((-Infinity).toString()); //'-Infinity'
Boolean()
情况就没有那么复杂了,有6种值会被转换为false,其余均为true
//以下都是false
console.log(Boolean());
console.log(Boolean(false));
console.log(Boolean(undefined));
console.log(Boolean(null));
console.log(Boolean(NaN));
console.log(Boolean(''));
console.log(Boolean(-0));
console.log(Boolean(+0));
console.log(Boolean(0));
console.log(Boolean(' ')); //true
ToPrimitive()
基本类型转数字的时候就介绍了底层函数ToNumber(),给出的表格其实缺少了参数为对象时的情况,现在这里补上
参数类型 | 结果 |
---|---|
Object | 1. primValue = ToPrimitive(input, Number) 2. 返回ToNumber(primValue). |
另一个底层函数ToString(),对于参数为对象有类似的处理
参数类型 | 结果 |
---|---|
Object | 1. primValue = ToPrimitive(input, String) 2. 返回ToString(primValue). |
这里引入了另一个底层函数ToPrimitive(input,preferredType)—把输入转换为初始值,这个函数调用结果如下
参数类型 | 结果 |
---|---|
基本数据类型 | 本身 |
Object | blablabla一大堆,咱也没看懂,下面介绍好理解的处理方式 |
Object情况的说明:
preferredType == Number
preferredType == String
toString()和valueOf()
toString()
上面介绍基本数据类型转字符串的时候,介绍了这个方法,那么对象用这个方法呢?
var a = [1,2,3]
var b = {val:4}
var c = function(x){
return x++
}
var d = new Date()
var e = /\d+/g
console.log(a.toString()); //'1,2,3'
console.log(b.toString()); //"[object object]"
console.log(c.toString()); //'function(x){ return x++ }'
console.log(d.toString()); //Thu Apr 09 2020 17:55:26 GMT+0800 (中国标准时间)
console.log(e.toString()); ///\d+/g
valueOf()
无论是哪种数据类型,返回参数本身,类型也不会变化,唯一特殊的是Date对象
var date = new Date()
console.log(date.valueOf()); //1586426466217,1970.1.1距今的毫秒数
另外包装类型Number、String、Boolean,也是Object类,用valueOf后类型转换为基本数据类型
var c = new Number(12)
console.log(c instanceof Number); //true
console.log(c instanceof Object); //true
console.log(c.valueOf()); //12
console.log(typeof c.valueOf()); //Number
转数字Number()
根据上面的分析,我们可以得出对象转数字的过程了
console.log(Number([1,2,3])); //NaN
console.log(Number([])); //0
console.log(Number([0])); //0
console.log(Number({val:4})); //NaN
console.log(Number({})); //NaN
console.log(Number(function(x){ return x++ })); //NaN
console.log(Number(new Date()));
console.log(Number(/\d+/g)); //NaN
试着分析[]和[1,2,3]的情况
[].valueOf() == [],不是基本数据类型
[].toString() == '',是基本数据类型
ToString('') == 0
[1,2,3].valueOf() == [1,2,3],不是基本数据类型
[1,2,3].toString() == '1,2,3',是基本数据类型
ToString('1,2,3') == NaN
转字符串
参考转数字的过程,有
console.log(String([1,2,3])); //'1,2,3'
console.log(String([])); //一个空格
console.log(String([0])); //'0'
console.log(String({val:4})); //'[object Object]'
console.log(String({})); //'[object Object]'
console.log(String(function(x){ return x++ })); //'function(x){ return x++ }'
console.log(String(new Date())); //'Thu Apr 09 2020 19:23:31 GMT+0800 (中国标准时间)'
console.log(String(/\d+/g)); //'/\d+/g'
都转为true!包装类型也是!
最常见的就是运算符+、==或者if语句中的条件判断,其实还有比较运算符、自增++、自减–等等
调用ToNumber(),对+后面的数据进行转换,那么这个就很熟悉了
//基本数据类型
console.log(+'12.3'); //12.3
console.log(+'-12.3'); //-12.3
console.log(+''); //0
console.log(+true); //1
console.log(+null); //+0
console.log(+undefined); //NaN
//对象
console.log(+[]); //0
console.log(+[ ]); //0
console.log(+[1]); //1
console.log(+[1,2]); //NaN
console.log(+{}); //NaN
console.log(+{val: 'happy'}); //NaN
console.log(+new Date()); //1586433193168,1970.1.1距今毫秒数
看规范吧
left = ToPrimitive(a),right = ToPrimitive(b),a和b是基本数据类型的话,left = a,right = b
如果上述两个值有一个是字符串,ToString(left)拼接ToString(right)
否则ToNumber(left)加上ToNumber(right)
两个数字相加遵循以下规则
console.log('1'+123); //'1123'
console.log(null+1); //1,两个都不是字符串,所以null转换为0,和1相加
console.log([]+[]); //'',经过ToPrimitive得到''+'' = ''
console.log(['1']+1); //'11',经过ToPrimitive得到'1'+1 = '11'
console.log([]+{}); //'[object Object]',经过ToPrimitive得到''+'[object Object]'
还是规范,看吐了,11.9.3,这里给出精简版的
//规则1,全部是false
console.log(NaN == NaN);
console.log(null == NaN);
console.log(undefined == NaN);
//规则2
console.log(null == null); //true
console.log(undefined == undefined); //true
console.log(null == {}); //false
//规则3.1
console.log(1 == true); //true
console.log('1' == true); //true
console.log(0 == false); //true
console.log('1' == 1); //true
//规则3.2
console.log({} == {});
console.log([] == false); //true
console.log([0] == 0); //true
console.log(['0'] == 0); //true
//规则4
console.log([0] == ['0']); //false,这个脑子瓦特了,肯定false
console.log(+0 == 0); //true
console.log(-0 == 0); //true
console.log(+0 == -0); //true