JavaScript 类型转换

164 阅读7分钟

转载自:

github.com/mqyqingfeng…

前言

JavaScript有8种数据类型,其中包含7种原始类型(基本类型):

  • Undefined
  • Null
  • Boolean(布尔值)
  • Number(数字)
  • String(字符串)
  • BigInt(大整数)
  • Symbol

以及引用类型

  • Object(对象)

其中的Object又包含了Array(数组),Function(函数),RegExp(正则),Date(日期)。

原始值转Boolean类型

使用Boolean函数可以将数据转换为布尔型,在JavaScript中,有6种值可以被装换为false,其余的都为true。

console.log(Boolean())  //false
console.log(Boolean(false))  //false
console.log(Boolean(undefined))  //false
console.log(Boolean(null))  //false
console.log(Boolean(0))  //false
console.log(Boolean(-1))  //false
console.log(Boolean(NaN))  //false
console.log(Boolean(""))  //false

//布尔型中的false,未定义undefined,空null,number型中0及以下的数以及NaN,string类型,不传参。

原始值转Number类型

使用Number函数将数据转换为数字类型,如果无法转换,则返回NaN。

参数类型返回结果
不传参返回0
undefinedNaN
null0
Booleantrue为1,false为0
number与之相等的值
string如果字符串中含有字母或空格或特殊字符的,则返回NaN。如果均为数字或小数,则会忽略最前面的所有0,然后转为对应的number型。如果是以0x或0X开头,则会解释为16进制数。
//不传参
console.log(Number())  //0
//undefined类型
console.log(Number(undefined))   //NaN
//null类型
console.log(Number(null));  //0
//Boolean类型
console.log(Number(true));  //1
console.log(Number(false));  //0
//number类型
console.log(Number(5));  //5
console.log(Number(-5));  //-5
//string类型
console.log(Number("123aabb"));  //NaN
console.log(Number("aabb123"));  //NaN
console.log(Number("123 123"));  //NaN
console.log(Number("123"));  //123
console.log(Number("-123"));  //-123
console.log(Number("12.3"));  //12.3
console.log(Number("000123"));  //123
console.log(Number("0x11"));  //17

在数据转number类型中,较常用的是parseIntparseFloatparseInt只解析整数,parseFloat则可以解析整数和浮点数,如果字符串前缀是"0x" 或者"0X",parseInt将其解释为十六进制数,parseInt和parseFloat 都会跳过任意数量的前导空格,尽可能解析更多数值字符,并忽略后面的内容。如果第一个非空格字符是非法的数字直接量,将最终返回NaN:

console.log(parseInt("3abc")) // 3
console.log(parseFloat("3.14abc")) // 3.14

console.log(parseInt("-12.34")) // -12
console.log(parseInt("0xFF")) // 255

console.log(parseFloat(".1")) // 0.1
console.log(parseInt("0.1")) // 0

console.log(parseInt("aabb123")) // NaN

原始值转String类型

使用 String 函数将数据转换成字符串类型。

参数类型返回结果
不传参空字符串
undefined"undefined"
null"null"
Booleantrue为"true",false为"false"
number与对应数字值相同的字符串
string与之相等的字符串
console.log(String()) // 空字符串

console.log(String(undefined)) // undefined
console.log(String(null)) // null

console.log(String(false)) // false
console.log(String(true)) // true

console.log(String(1)) // 1
console.log(String(-1)) // -1
console.log(String(NaN)) // NaN

Object类型

可以用原始值通过调用 String()、Number() 或者 Boolean() 构造函数,转换为它们各自的包装对象。

var a = 1;
console.log(typeof a); // number

var b = new Number(a);
console.log(typeof b); // object

对象转字符串和数字

JavaScript的对象向别的类型转换都是通过调用待转换的对象的两个方法来实现的。一个是toString,一个是valueOf。

所有的对象除了null和undefined以外的任何值都具有toString方法,通常情况下,和使用String方法返回的结果一致。 当调用对象的toString方法时,其实调用的是Object.prototype上的toString方法。 数组,函数,日期,RegExp的toString规则如下:

  • 数组的toString会将每一个数组元素转换为一个字符串,然后再在各个元素中间添加逗号合并成一个长的字符串。
  • 函数的toString会直接返回源代码字符串。
  • 日期的会返回可读日期和时间字符串。
  • RegExp的会返回一个表示正则表达式直接量的字符串。
//对象
console.log(({}).toString()) // [object Object]
//数组
console.log([].toString()) // ""
console.log([0].toString()) // 0
console.log([1, 2, 3].toString()) // 1,2,3
//函数
console.log((function(){var a = 1;}).toString()) // function(){var a = 1;}
//正则表达式
console.log((/\d+/g).toString()) // /\d+/g
//日期时间
console.log((new Date(2010, 0, 1)).toString()) // Fri Jan 01 2010 00:00:00 GMT+0800 (CST)

另一个转换函数是valueOf,表示对象的原始值。默认的valueOf返回这个对象本身,数组,函数,正则都会直接返回对象本身。日期是一个例外,它会返回一个内容表示,即1970年1月1日以来的毫秒数。

var date = new Date(2017, 4, 21);
console.log(date.valueOf()) // 1495296000000

使用Number和String方法将对象转为数组和字符串

当我们用Number和String对一个值进行转换的时候,如果该值是基本类型的值,那就按照前面的“原始值转数字”和“原始值转字符”对应的转换关系进行转换。如果不是基本类型的值,那就需要引入一个新的方法 ToPrimitive 了。先将其转换为基本类型,然后再参照前面的“原始值转数字”和“原始值转字符”对应的转换关系进行转换。

ToPrimitive(input,[PreferredType])

第一个参数是input,表示要处理的输入值。 第二个参数是PreferredType,非必填,表示的是希望转换成的类型,有两个值可以选,Number 或者 String。如果这个参数不输入,而input是日期类型,则相当于是传入了String,否则,都相当于是传入 number。 如果传入的 input 是 Undefined、Null、Boolean、Number、String类型,直接返回该值。 如果是ToPrimitive(obj, Number),处理步骤如下:

  1. 如果 obj 为 基本类型,直接返回
  2. 否则,调用 valueOf 方法,如果返回一个原始值,则 JavaScript 将其返回。
  3. 否则,调用 toString 方法,如果返回一个原始值,则 JavaScript 将其返回。
  4. 否则,JavaScript 抛出一个类型错误异常。

如果是 ToPrimitive(obj, String),处理步骤如下:

  1. 如果 obj为 基本类型,直接返回。
  2. 否则,调用 toString 方法,如果返回一个原始值,则 JavaScript 将其返回。
  3. 否则,调用 valueOf 方法,如果返回一个原始值,则 JavaScript 将其返回。
  4. 否则,JavaScript 抛出一个类型错误异常。

对象转字符串

  1. 如果对象具有toString方法,则直接调用。如果返回一个原始值,JavaScript将这个值转换为字符串,并返回这个字符串结果。
  2. 如果对象没有toString方法,或者有但是不返回一个原始值,那么JavaScript会调用它。如果返回的是原始值,则将值转换为字符串,并返回这个字符串的结果。
  3. 如果从toString或者valueOf无法得到一个原始值,则会抛出一个类型错误的异常。

对象转数字

  1. 如果对象具有 valueOf 方法,且返回一个原始值,则 JavaScript将这个原始值转换为数字并返回这个数字
  2. 否则,如果对象具有 toString 方法,且返回一个原始值,则 JavaScript 将其转换并返回。
  3. 否则,JavaScript 抛出一个类型错误异常。

举个例子:

console.log(Number({})) // NaN
console.log(Number({a : 1})) // NaN

console.log(Number([])) // 0
console.log(Number([0])) // 0
console.log(Number([1, 2, 3])) // NaN
console.log(Number(function(){var a = 1;})) // NaN
console.log(Number(/\d+/g)) // NaN
console.log(Number(new Date(2010, 0, 1))) // 1262275200000
console.log(Number(new Error('a'))) // NaN

注意,在这个例子中,[] 和 [0] 都返回了 0,而 [1, 2, 3] 却返回了一个 NaN。我们分析一下原因:

当我们 Number([]) 的时候,先调用 [] 的 valueOf 方法,此时返回 [],因为返回了一个对象而不是原始值,所以又调用了 toString 方法,此时返回一个空字符串,接下来调用 ToNumber 这个规范上的方法,参照对应表,转换为 0, 所以最后的结果为 0。

而当我们 Number([1, 2, 3]) 的时候,先调用 [1, 2, 3] 的 valueOf 方法,此时返回 [1, 2, 3],再调用 toString 方法,此时返回 1,2,3,接下来调用 ToNumber,参照对应表,因为无法转换为数字,所以最后的结果为 NaN。