简单总结一下JS中的部分显/隐式强制类型转换。
1、类型
JS中6种基本类型:
Undefined, Null, Boolean, Number, Symbol, or String
以及对象:
member of the type Object
Boolean的真假值
其他类型转换为Boolean
类型时,一般遵从下面的表值映射:
Undefined Return false.
Null Return false.
Boolean Return argument.
Number If argument is +0, -0, or NaN, return false; otherwise return true.
String If argument is the empty String (its length is zero), return false; otherwise return true.
Symbol Return true.
Object Return true
通过!
操作符转换为Boolean
类型。
&&
、||
操作符在表达式中会把值强制转换为Boolean
类型。
但是&&
、||
操作符返回的不是布尔值。
2、转换为数字、字符串
0.Null/Boolean/Undefined/Symbol => 字符串/数字
以下列举了几种Null/Boolean/Undefined/Symbol
类型转换为数字类型的情况:
- Null值:=>字符串
'null'
,=>数字0
- Boolean值:
true
和false
,转换为字符串分别是:'true'
,'false'
;转换为数字分别是1
,0
- undefined值:=>字符串
'undefined'
,=>数字NaN
- Symbol值无法被转换为字符串/数字
1.字符串=>数字
以下列举了几种字符串类型转换为数字类型的情况:
+
、-
操作符 + 字符串,发生强制类型转换- 字符串 + 操作符 + 数字,发生强制类型转换
- 调用
Number
- 调用
parseInt
- 使用
==
操作符时
具体的转换情境如下:
1 | let num; |
总的来说:
-
操作符和调用Number
的方式差不多,字符串中出现0~9以外的值,例如字母等,不论位置,都会返回NaN的结果。parseInt
第一个参数是字符串,如果不是,会先转换为字符串再进行求值。与1和2的方式不同,parseInt
会解析字符串中非数字在数字后面的字符串,如’1234.3ssss’,返回1234。
值得注意的是,空字符串会转换为数字0。
2.Object=>数字/字符串
Object
转换为数字/字符串会进行ToPrimitive
抽象操作,而且顺序一般是valueOf
、toString
,如果valueOf
方法返回基本类型值,就使用该返回值,否则就调用toString
:
1 | // 1.valueOf返回非基本类型值,toString返回1, |
3.ToPrimitive抽象操作
占坑
3、使用==时发生的类型转换
执行x == y
:
x
与y
类型相同,则返回x===y
的结果。- 如果
x
与y
任意一方为undefined
,另一方为null
则返回true
。 - 如果
x
与y
有一方为字符串/布尔值,则为字符串/布尔值的一方执行ToNumber的抽象操作,转换为数字。 - 如果
x
与y
有一方为对象(包括数组、包装对象等子对象),则为对象一方执行ToPrimitive抽象操作。
以上参考自如下的ES10标准:
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
- If Type(x) is the same as Type(y), then
a. Return the result of performing Strict Equality Comparison x === y.- If x is null and y is undefined, return true.
- If x is undefined and y is null, return true.
- If Type(x) is Number and Type(y) is String, return the result of the comparison x == ! ToNumber(y).
- If Type(x) is String and Type(y) is Number, return the result of the comparison ! ToNumber(x) == y.
- If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y.
- If Type(y) is Boolean, return the result of the comparison x == ! ToNumber(y).
- If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x ==
ToPrimitive(y).- If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison
ToPrimitive(x) == y.- Return false.
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:- If Type(x) is different from Type(y), return false.
- If Type(x) is Number, then
a. If x is NaN, return false.
b. If y is NaN, return false.
c. If x is the same Number value as y, return true.
d. If x is +0 and y is -0, return true.
e. If x is -0 and y is +0, return true.
f. Return false.- Return SameValueNonNumber(x, y).
NOTE
This algorithm differs from the SameValue Algorithm in its treatment of signed zeroes and NaNs.
从规范中可以看出,如果检测到双方类型相等,则会进行全等比较;否则,在进行相等比较的过程中,会进行abstract operation
,即:ToNumber
和ToPrimitive
转换类型进行比较,最终比较的是两边的数字。
ToNumber
即转换为数字类型,上文说明了转换的情景。
对象进行ToPrimitive
操作,一般会调用valueOf
和toString
方法。故可以通过改写valueOf
和toString
方法使ToPrimitive
返回特定值。
参考
- 你不知道的JS(中)
- ECMA-262