什么是Javascript中的类型强制转换Coercion?

  类型强制Coercion是将值从一种类型转换为另一种类型的过程(例如字符串转换为数字,对象转换为布尔值等)。任何类型,无论是原始类型还是对象,都是类型强制的有效主体

  coercion有两种表现形式:显式和隐式。

  下面是显式明确方式的案例:

var a = "42";

var b = Number(a);

a; // "42"
b; // 42 -- 数字型!

 

  下面是隐式转换,也就是悄悄在做其他事时转换了。

var a = "42";

var b = a * 1; // "42" 已经隐式转换到 42

a; // "42"
b; // 42 -- 数字型!

  在90%的使用案例中,最好避免隐式类型强制。隐式强制是一种双刃剑:它是挫折和缺陷的重要来源,但也是一种有用的机制,它允许我们在不失去可读性的情况下编写更少的代码。

  但是,JavaScript中只有三种类型的转换:

  • 转换到 string
  • 转换到 boolean
  • 转换到 number

 原始类型和对象之间转换是不同的,但是原始类型和对象只能按照这三种方式转换。

字符串转换

 要将值显式转换为字符串,请应用该String()函数。当任何操作符是字符串时,使用+二元运算符会触发隐式强制:

String(123)//显式
123 +''//隐式

 所有原始值都会自然地转换为字符串:

String(123)                   // '123'
String(-12.3) // '-12.3'
String(null) // 'null'
String(undefined) // 'undefined'
String(true) // 'true'
String(false) // 'false'

 

Symbol(符号 是ES6引入了一种新的原始数据类型,表示独一无二的值。它是JavaScript语言的第七种数据类型。Symbol转换有点棘手,因为它只能显式转换,但不能隐式转换:

String(Symbol('my symbol'))   // 'Symbol(my symbol)'
'' + Symbol('my symbol') // TypeError is thrown

布尔转换

要将值显式转换为布尔值,请应用该Boolean()函数。
而隐式转换发生在逻辑上下文中,或由逻辑运算符(|| && !)触发。

Boolean(2)          // 显式
if (2) { ... } // 隐式
!!2 // 隐式
2 || 'hello' // 隐式

逻辑运算符,如||和&&做布尔转换内部,但实际上将返回原来的操作数的值,即使他们不是布尔值。

//返回数字123,而不是返回true 
//'hello'与123仍在内部强制转换为boolean以计算表达式
let x ='hello' && 123; // x === 123

一旦可能有两个的布尔转换结果:true或者false,它就更容易记住false:

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

不在上述列表中的任意值都会被转换为true,包括对象,函数Array,Date,用户定义的类型,等等。符号Symbols 是true。空对象和数组也是true的值:

Boolean({})             // true
Boolean([]) // true
Boolean(Symbol()) // true
!!Symbol() // true
Boolean(function() {}) // true

 

数字转换

对于显式转换,只需应用Number()函数,就像使用Boolean()和执行一样String() 。

隐式转换很棘手,因为它在更多情况下被触发:

  • 比较运算符(>,<,<=,>=)
  • 按位运算符(| & ^ ~)
  • 算术运算符(- + * / %)。注意, 进行二进制文件+操作时,当任何一个操作数是字符串时,不会触发数字转换。
  • 一元运算+符
  • 松散的平等运算符==(包括  !=)。 
    请注意,使用两个等于号==,当两个操作数都是字符串时,不会触发数字转换。
Number('123')   // 显式
+'123' // 隐式
123 != '456' // 隐式
4 > '5' // 隐式
5/null // 隐式
true | 0 // 隐式

要记住两个特殊规则

1. ==到null或undefined,数字转换不会发生。null仅等于null或等于或undefined等于其他任何东西。

2. NaN甚至不等于任何东西.

 

对象转换

对象和JS引擎遇到表达式[1] + [2,3]时,首先需要将对象转换为原始值,然后将其转换为最终类型。仍然只有三种类型的转换:数字,字符串和布尔值。

最简单的情况是布尔转换:无论对象或数组是否为空,任何非原始值都始终
被强制转换  true。

通过内部[[ToPrimitive]]方法将对象转换为原始类型,该方法负责数字和字符串转换。

 

总结

规则1 :所有运算符将不同类型的操作数转换为数字。

例外1逻辑运算符将它们转换为布尔值。

例外2:对象操作使用==和+ 时是使用ToPrimitive,首先为Date对象尝试toString,然后返回对象的包装符号值Symbol,null与undefined只在使用==时仅考虑彼此相等,不会转化为任何其它类型。

例外3:如果其中一个操作数是字符串,则+操作员也将另一个操作数转换为字符串。

Javascript/ES6专题

Javascript专题