简单总结一下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