一、引言
开始之前,我们先来看一些令人疑惑的现象。
if({}){
console.log('hello1'); //hello1
}
if({a: 1}){
console.log('hello2'); //hello2
}
if([]){
console.log('hello3'); //hello3
}
console.log({} == {}); //false
console.log({} === {}); //false
console.log([] == []); //false
console.log([] == ![]); //true
这居然都能正常输出,而且看似相等的东西居然不相等,看似不相等的东西居然相等。这是为什么呢?这就要讲到今天的主角数据类型转换了。
在JavaScript编程中,数据类型转换是非常常见的操作,它可以让我们方便地将不同类型的数据进行比较、计算、存储等操作。本文将介绍JavaScript中的数据类型转换技术,包括其他类型到基本类型的转换、基本类型到对象类型的转换以及一元运算符和二元运算符。
JavaScript这门语言中的数据类型包括基本数据类型和引用数据类型。 其中,基本数据类型包括Number(数值)、String(字符串)、Boolean(布尔值)、BigInt(大整数)、Null(空)、Undefined(未定义)、Symbol。Symbol 是ES6引入的一种新的数据类型,表示一个独一无二的值,可以用来避免命名冲突。
引用数据类型 Object(对象)、Array(数组)、Function(函数)、RegExp(正则表达式)、Date(日期)。
二、其他类型转基本数据类型
1.其他类型转布尔类型
将其他数据类型转换为Boolean,这个没有太多道理可言,记住即可。
console.log(Boolean()); // false
console.log(Boolean(false)); // false
console.log(Boolean(0)); // false
console.log(Boolean('')); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(-1)); // true
console.log(Boolean(-6.6)); // true
console.log(Boolean(1)); // true
console.log(Boolean({})); // true
console.log(Boolean([])); // true
console.log(Boolean(Function)); // true
console.log(Boolean(new Boolean(false))); // true
console.log(Boolean(new Date())); // true
在以上的代码中,除了前七行代码输出 false 外,其余的值转布尔类型都为 true,传的参数为数字时,只要不是0,结果都为true,传正0负0都是false,对象类型转布尔值结果都为true。
2.其他类型转数字类型
2.1 使用Number()方法
Number()函数:将任意数据类型转换为对应的数值。如果转换失败,则返回NaN。什么值都不传时会默认的返回0,如果字符串中有非数字的内容,则转换为NaN,如果字符串是一个空串或者是一个全是空格的字符串,则转换为0。
console.log(Number()); // 0
console.log(Number(undefined)); // NaN
console.log(Number(null)); // 0
console.log(Number('123')); // 123
console.log(Number('-123')); // -123
console.log(Number('1.23')); // 1.23
console.log(Number('000123')); // 123
console.log(Number('-000123')); // -123
console.log(Number('0x11')); // 17
console.log(Number('你好啊')); // NaN
console.log(Number('')); // 0
console.log(Number(' ')); // 0
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(1.56)); // 1.56
console.log(Number('10010')); // 10010
console.log(Number('123 123')); // NaN
console.log(Number(000666)); // 438 参数是八进制
console.log(+[]); // 0
2.2 使用parseInt()函数
parseInt()函数将一个字符串解析成一个整数。它会忽略字符串前面的空格,直到找到第一个非空格字符。如果第一个非空格字符不是数字或者正负号,返回 NaN。如果第一个非空格字符是数字或者正负号,继续解析直到找到一个无效的字符为止。parseInt()函数还可以解析十进制、十六进制和八进制数。
console.log(parseInt(" 123")); //123
console.log(parseInt("123")); //123
console.log(parseInt("12.34")); //12
console.log(parseInt("hello123")); //NaN
console.log(parseInt('10abc')); //10
console.log(parseInt('0x10')); //16
console.log(parseInt('10abc')); //10
console.log(parseInt(11, 2)); //3
console.log(parseInt('11', 16)); //17
当解析十六进制数时,parseInt()函数会自动忽略字符串开头的 0x,但在指定进制时应该写上前缀。
2.3 parseFloat()函数
parseFloat()函数将一个字符串解析成一个浮点数。它会忽略字符串前面的空格,直到找到第一个非空格字符。如果第一个非空格字符不是数字或者正负号,返回 NaN。如果第一个非空格字符是数字或者正负号,继续解析直到找到一个无效的字符为止。parseFloat() 函数不会解析十六进制数,它只能解析十进制数。
console.log(parseFloat('3.14')); //3.14
console.log(parseFloat('3.14abc')); //3.14
console.log(parseFloat(' 3.14abc')); //3.14
console.log(parseFloat('abc3.14')); //NaN
3.其他类型转字符串类型
3.1 使用toString()方法
每个 JavaScript 对象都有一个 toString() 方法,可以将一个对象转换成字符串类型。对于大多数内置对象,toString() 方法的实现都是返回对象的字符串表示。例如,对于数字,toString() 返回数字的字符串形式。对于布尔值,toString() 返回 "true" 或 "false"。对于数组,toString() 方法返回数组元素的逗号分隔字符串。对于对象,toString() 返回一个 [object Object] 格式的字符串。
console.log((123).toString()); //'123'
console.log((true).toString()); //'true'
console.log(({}).toString()); //'[object Object]'
console.log(([1,2,3]).toString()); //'1,2,3'
console.log((null).toString());
//TypeError: Cannot read property 'toString' of null
console.log((undefined).toString());
//TypeError: Cannot read property 'toString' of undefined
3.2 使用String()方法
String() 函数可以将任意类型的数据转换成字符串类型。它的工作原理是先将数据转换成字符串值,然后返回这个字符串值。 需要注意的是,String() 函数对于 null 和 undefined 参数会返回字符串 "null" 和 "undefined"。对于对象和数组,String() 函数和 toString() 方法的行为是一致的。
console.log(String()); //'' 输出空字符串
console.log(String(undefined)); //'undefined'
console.log(String(true)); //'true'
console.log(String(false)); //'false'
console.log(String(123)); //'123'
console.log(String(null)); //'null'
console.log(String(NaN)); //'NaN'
console.log(String(Infinity)); //'Infinity'
console.log(String({a:1,b:2})); //'[object Object]'
console.log(String([1,2,3])); //'1,2,3'
三、对象类型到基本类型的转换
JavaScript 中,对象类型到基本类型的转换可以使用对象的 valueOf() 和 toString() 方法,这是对象原型上就有的方法。当对象参与到运算或比较时,JavaScript 引擎会自动将对象转换为基本类型,这种转换被称为“对象到基本类型的自动类型转换”或“拆箱转换”。默认情况下,JavaScript 引擎将对象转换为字符串类型,具体的转换规则如下:
1.对象类型转数字类型
会执行自带的 ToPrimitive(obj, Number)
- 判断obj是否为基本类型,是则返回
- 调用对象自带的valueOf方法,如果能得到一个原始类型,则返回
- 调用对象自带的toString方法,如果能得到一个原始类型,则返回
- 报错
console.log('1' + []); //'1'
如图所示,在这里,字符串1是基本类型,空数组是对象类型,加号会导致对象往基本类型上转,那么是转数字还是转字符串呢?转数字,因为加法天生就是为四则运算准备的,所以会转为数字。然后按照上面所写的转换的步骤,先调用valueOf
方法,发现转不动,再调用toString
方法,转为空字符串,最后式子里都是字符串,都是基本类型,相加得'1'
。
同理可得以上,但是注意字符串加任何东西都是字符串,任何东西加字符串也是字符串(注意只是加法运算,没说减法)
2.对象类型转字符串类型
会执行自带的 ToPrimitive(obj, String)
- 判断obj是否为基本类型,是则返回
- 调用对象自带的toString方法,如果能得到一个原始类型,则返回
- 调用对象自带的valueOf方法,如果能得到一个原始类型,则返回
- 报错
四、一元操作符
当 - 或 + 运算作为一元操作符时,会调用ToNumber()方法处理该值(非Number类型的值),转不了的变为NaN。
使用+
时,右边的那个值会被Number()方法转成数字,所以这样写更简便。
当ToNumber()
转不动时,要先调用ToPrimitive()
方法去转。
console.log(+{}); //NaN
console.log(+[]); //0
console.log(+'666'); //666
console.log(+NaN); //NaN
console.log(+['1','2','3']); //NaN
五、二元操作符
- a + b
- 1.leftValue = ToPrimitive(a)
- 2.rightValue = ToPrimitive(b)
- 3.如果 leftValue 是字符串或者 rightValue 是字符串,则返回ToString(leftValue) 和 ToString(rightValue) 的拼接结果
- 4.否则返回 ToNumber(leftValue) + ToNumber(rightValue)
console.log('1' + 1); //'11'
console.log(undefined + 1); //NaN
console.log(null + 1); //1 相当于0+1
console.log([] + []); //''
console.log([] + {}); //'[object Object]'
console.log({} + []);
//0 注意谷歌浏览器此时会把{}看成块级作用域,块级语法,而不是看成一个对象
console.log(({}) + []); //'[object Object]'
六、最后的话
最后附上网上比较经典的一张类型转换的表:
感谢你阅读这篇文章,如果你觉得写得还行的话,不要忘记点赞、评论、收藏哦!能力一般,水平有限,如有问题欢迎大家指正,祝大家生活愉快!
以上输出结果均以谷歌浏览器控制台的输出结果为准,一切内容以ECMAScript 5.1官方文档为准。es5.github.io/#x15.7.1.1