类型转换

转Boolean

在条件判断时,除了 undefinednullfalseNaN''0-0,其他所有值都转为 true,包括所有对象。

对象转基本类型

对象在转换基本类型时,首先会调用 valueOf 然后调用 toString。并且这两个方法你是可以重写的。

  1. let a = {
  2. valueOf() {
  3. return 0
  4. }
  5. }

当然你也可以重写 Symbol.toPrimitive ,该方法在转基本类型时调用优先级最高。

  1. let a = {
  2. valueOf() {
  3. return 0;
  4. },
  5. toString() {
  6. return '1';
  7. },
  8. [Symbol.toPrimitive]() {
  9. return 2;
  10. }
  11. }
  12. 1 + a // => 3
  13. '1' + a // => '12'

四则运算符

只有当加法运算时,其中一方是字符串类型,就会把另一个也转为字符串类型。其他运算只要其中一方是数字,那么另一方就转为数字。并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串。

  1. 1 + '1' // '11'
  2. 2 * '2' // 4
  3. [1, 2] + [2, 1] // '1,22,1'
  4. // [1, 2].toString() -> '1,2'
  5. // [2, 1].toString() -> '2,1'
  6. // '1,2' + '2,1' = '1,22,1'

对于加号需要注意这个表达式 'a' + + 'b'

  1. 'a' + + 'b' // -> "aNaN"
  2. // 因为 + 'b' -> NaN
  3. // 你也许在一些代码中看到过 + '1' -> 1

== 操作符

类型转换 - 图1

上图中的 toPrimitive 就是对象转基本类型。

这里来解析一道题目 [] == ![] // -> true ,下面是这个表达式为何为 true 的步骤

  1. // [] 转成 true,然后取反变成 false
  2. [] == false
  3. // 根据第 8 条得出
  4. [] == ToNumber(false)
  5. [] == 0
  6. // 根据第 10 条得出
  7. ToPrimitive([]) == 0
  8. // [].toString() -> ''
  9. '' == 0
  10. // 根据第 6 条得出
  11. 0 == 0 // -> true

比较运算符

  1. 如果是对象,就通过 toPrimitive 转换对象
  2. 如果是字符串,就通过 unicode 字符索引来比较