解密JavaScript中的数据类型转换:从基础类型到复杂类型!

1,340 阅读7分钟

一、引言

开始之前,我们先来看一些令人疑惑的现象。

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

11.jpg

这居然都能正常输出,而且看似相等的东西居然不相等,看似不相等的东西居然相等。这是为什么呢?这就要讲到今天的主角数据类型转换了。

在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)

  1. 判断obj是否为基本类型,是则返回
  2. 调用对象自带的valueOf方法,如果能得到一个原始类型,则返回
  3. 调用对象自带的toString方法,如果能得到一个原始类型,则返回
  4. 报错
console.log('1' + []); //'1'

221.jpg

如图所示,在这里,字符串1是基本类型,空数组是对象类型,加号会导致对象往基本类型上转,那么是转数字还是转字符串呢?转数字,因为加法天生就是为四则运算准备的,所以会转为数字。然后按照上面所写的转换的步骤,先调用valueOf方法,发现转不动,再调用toString方法,转为空字符串,最后式子里都是字符串,都是基本类型,相加得'1'

222.jpg

同理可得以上,但是注意字符串加任何东西都是字符串,任何东西加字符串也是字符串(注意只是加法运算,没说减法)

2.对象类型转字符串类型

会执行自带的 ToPrimitive(obj, String)

  1. 判断obj是否为基本类型,是则返回
  2. 调用对象自带的toString方法,如果能得到一个原始类型,则返回
  3. 调用对象自带的valueOf方法,如果能得到一个原始类型,则返回
  4. 报错

四、一元操作符

当 - 或 + 运算作为一元操作符时,会调用ToNumber()方法处理该值(非Number类型的值),转不了的变为NaN。

333.jpg

使用+时,右边的那个值会被Number()方法转成数字,所以这样写更简便。

444.jpg

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]'

六、最后的话

最后附上网上比较经典的一张类型转换的表:

1.jpg

2.jpg

感谢你阅读这篇文章,如果你觉得写得还行的话,不要忘记点赞、评论、收藏哦!能力一般,水平有限,如有问题欢迎大家指正,祝大家生活愉快!

以上输出结果均以谷歌浏览器控制台的输出结果为准,一切内容以ECMAScript 5.1官方文档为准。es5.github.io/#x15.7.1.1