JavaScript(三)数据类型的转换

2019-07-28  本文已影响0人  范小饭_

一、概述

JavaScript 是一种动态类型语言,变量没有类型限制,可以随时赋予任意值var x = y ? 1 : 'a';
虽然变量的数据类型是不确定的,但是各种运算符对数据类型是有要求的。如果运算符发现,运算子的类型与预期不符,就会自动转换类型。比如,减法运算符预期左右两侧的运算子应该是数值,如果不是,就会自动将它们转为数值。'4' - '3' // 1

二、抽象值操作

2.1 ToString

抽象操作ToString负责处理非字符串到字符串的强制类型转换。

基本类型值的字符串化规则为:null转换为"null",undefined转换为"undefined",true转换为""true"。数字的字符串化遵循通用规则,那些极小和极大的数字使用指数形式:

对普通对象来说,除非自行定义,否则toString()返回内部属性[[Class]]的值,如"[object Object]"。

数组的默认toString()方法经过了重新定义,将所有单元字符串化以后再用","连接起来:

var a = [1,2,3]
a.toString()    //"1,2,3"

2.2 ToNumber

抽象操作ToNumber将非数字值转换为数字值。

其中true转换为1,false转换为0,undefined转换为NaN,null转换为0。

ToNumber对字符串的处理基本遵循数字常量的相关规则(字符串中含有非数字类型字符返回NaN)。

对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

2.3 ToPrimitive

抽象方法ToPrimitive将对象值转换为相应的基本类型值。该方法会首先检查该值是否有valueOf()方法,如果有并且返回基本类型值,就使用该值进行强制类型转换;如果没有就使用toString()的返回值(如果存在)来进行强制类型转换;如果valueOf()和toString()均不返回基本类型值,会产生TypeError错误。

从ES5开始,使用Object.create(null)创建的对象原型属性为null,并且没有valueOf()和toString()方法,因此无法进行强制类型转换。

2.4 ToBoolean

抽象操作ToBoolean将非布尔值转换为布尔值。

假值

以下这些值是假值

假值对象

var a = new Boolean(false)
var b = new Boolean(0)
var c = new Boolean("")

var d = Boolean(a && b && c)    //true

a,b,c都是封装了假值的对象,但是d为true,说明a、b、c都为true。因此假值对象并非封装了假值的对象。

假值对象看起来和普通对象并无二致,但将它们强制类型转换为布尔值时结果为false。最常见的例子是document.all,它是一个类数组对象,包含了页面上所有元素,它以前曾是一个真正意义上的对象,布尔强制类型转换结果为true,不过现在它是一个假值对象。

真值

真值就是假值列表之外的值

三、显式强制转换

强制转换主要指使用Number()、String()和Boolean()三个函数,手动将各种类型的值,分别转换成数字、字符串或者布尔值。

显式转换为数字

Number(), parseInt(), parseFloat()

Number()
使用Number函数,可以将任意类型的值转化成数值

原始类型值

// 数值:转换后还是原来的值
Number(324) // 324

// 字符串:如果可以被解析为数值,则转换为相应的数值
Number('324') // 324

// 字符串:如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN

// 空字符串转为0
Number('') // 0

// 布尔值:true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0

// undefined:转成 NaN
Number(undefined) // NaN

// null:转成0
Number(null) // 0

对象
简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组

Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5

1,调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。

2,如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。

3,如果toString方法返回的是对象,就报错。

var obj = {x: 1};
Number(obj) // NaN

// 等同于
if (typeof obj.valueOf() === 'object') {
  Number(obj.toString());
} else {
  Number(obj.valueOf());
}

Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN

parseInt

parseInt()针对的是将字符串解析为数字,非字符串参数会首先被强制转化为字符串.

解析字符串中的浮点数可以使用parseFloat()

var a = '42px'
parseInt(a)   // 42

显式转换为字符串

String函数可以将任意类型的值转化成字符串,转换规则如下

原始类型值

数值:转为相应的字符串。
字符串:转换后还是原来的值。
布尔值:true转为字符串"true",false转为字符串"false"。
undefined:转为字符串"undefined"。
null:转为字符串"null"。

String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"

对象
String方法背后的转换规则,与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。

String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"

1,先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
2,如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
3,如果valueOf方法返回的是对象,就报错。

String({a: 1})
// "[object Object]"

// 等同于
String({a: 1}.toString())
// "[object Object]"

显式转为布尔值

一元运算符

一元运算符!可以显式的将值强制转换为布尔值,同时还将真值反转为假值(或将假值反转为真值)所以显式强制类型转换为布尔值最常用的方法是!!,以为第二个!会将结果反转回原值

var a =  '0'
!!a  // true

var b = ''
!!b  // fasle

Boolean()

Boolean()函数可以将任意类型的值转为布尔值。
它的转换规则相对简单:除了以下五个值的转换结果为false,其他的值全部为true。

1、undefined
2、null
3、0(包含-0和+0)
4、NaN
5、''(空字符串)

Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false

所有对象(包括空对象)的转换结果都是true,甚至连false对应的布尔对象new Boolean(false)也是true

Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true

四、隐式强制类型转换

隐式类型转换是指那些隐蔽的强制类型转换。

隐式转换为布尔值

if(), for(..;..;..;), while(...), ? : 三元运算,|| ,&& (作为条件判断表达式)

JavaScript 遇到以上预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值。系统内部会自动调用Boolean函数
1、undefined
2、null
3、+0或-0
4、NaN
5、''(空字符串)

if ( !undefined
  && !null
  && !0
  && !NaN
  && !''
) {
  console.log('true');
} // true

隐式转换为字符串

+运算符既能用于数字转化,也能用于字符串拼接。如果+的其中一个操作数是字符串,则执行字符串拼接,否则执行数字加法。

'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"

隐式转换为数值

除了加法运算符(+)有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。

-是数字减法运算符,因为 a-0 会将 a 强制类型转为数字。

a*1a/1也可以将a转换为数字,不过不常见。

'5' - '2' // 3
'5' * '2' // 10
true - 1  // 0
false - 1 // -1
'1' - 1   // 0
'5' * []    // 0
false / '5' // 0
'abc' - 1   // NaN
null + 1 // 1
undefined + 1 // NaN

五、总结

JavaScript的类型转换可以分为显式类型换和隐式类型转换

强制类型转换:Number() ,parseInt(), parseFloat(),String(),Boolean()、!!!

隐式类型转换
+-*-、 if()、 for(..;..;..;)、 while(...)、 ? : 三元运算、||(作为条件判断表达式) 、&& (作为条件判断表达式)

本文参考:
1、JavaScript 教程
2、《你不知道的JavaScript(中)》

上一篇 下一篇

猜你喜欢

热点阅读