3 数据类型转换

大家都知道 JS 中在使用运算符号或者对比符时,会自带隐式转换,规则如下:

3.1 转化规则

  • -、*、/、%:一律转换成数值后计算
  • +:
    • 数字 + 字符串 = 字符串, 运算顺序是从左到右
    • 数字 + 对象, 优先调用对象的valueOf -> toString
    • 数字 + boolean/null -> 数字
    • 数字 + undefined -> NaN
  • [1].toString() === '1'
  • {}.toString() === '[object Object]'
  • NaN !== NaN 、+undefinedNaN

首先我们要知道,在 JS 中类型转换只有三种情况,分别是:

  • 转换为布尔值
  • 转换为数字
  • 转换为字符串

类型转换

3.2 转Boolean

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

3.3 对象转原始类型是根据什么流程运行的

对象转原始类型,会调用内置的[ToPrimitive]函数,对于该函数而言,其逻辑如下:

  • 如果有Symbol.toPrimitive()方法,优先调用再返回
  • 调用valueOf(),如果转换为原始类型,则返回
  • 调用toString(),如果转换为原始类型,则返回
  • 如果都没有返回原始类型,会报错
    var obj = {
      value: 3,
      valueOf() {
        return 4;
      },
      toString() {
        return '5'
      },
      [Symbol.toPrimitive]() {
        return 6
      }
    }
    console.log(obj + 1); // 输出7

3.4 如何让if(a == 1 && a == 2)条件成立

其实就是上一个问题的应用。

    var a = {
      value: 0,
      valueOf: function() {
        this.value++;
        return this.value;
      }
    };
    console.log(a == 1 && a == 2);//true

3.5 四则运算符

它有以下几个特点:

  • 运算中其中一方为字符串,那么就会把另一方也转换为字符串
  • 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串
    1 + '1' // '11'
    true + true // 2
    4 + [1,2,3] // "41,2,3"
  • 对于第一行代码来说,触发特点一,所以将数字 1 转换为字符串,得到结果 '11'
  • 对于第二行代码来说,触发特点二,所以将 true 转为数字 1
  • 对于第三行代码来说,触发特点二,所以将数组通过 toString转为字符串 1,2,3,得到结果 41,2,3

另外对于加法还需要注意这个表达式 'a' + + 'b'

    'a' + + 'b' // -> "aNaN"
  • 因为 + 'b' 等于 NaN,所以结果为 "aNaN",你可能也会在一些代码中看到过 + '1'的形式来快速获取 number 类型。
  • 那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字
    4 * '3' // 12
    4 * [] // 0
    4 * [1, 2] // NaN

3.6 比较运算符

  • 如果是对象,就通过 toPrimitive 转换对象
  • 如果是字符串,就通过 unicode 字符索引来比较
    let a = {
      valueOf() {
        return 0
      },
      toString() {
        return '1'
      }
    }
    a > -1 // true

在以上代码中,因为 a 是对象,所以会通过 valueOf 转换为原始类型再比较值。

3.7 [] == ![]结果是什么?为什么?

  • == 中,左右两边都需要转换为数字然后进行比较
  • []转换为数字为0
  • ![] 首先是转换为布尔值,由于[]作为一个引用类型转换为布尔值为true
  • 因此![]false,进而在转换成数字,变为0
  • 0 == 0 , 结果为true

3.8 == 和 ===有什么区别

===叫做严格相等,是指:左右两边不仅值要相等,类型也要相等,例如'1'===1的结果是false,因为一边是string,另一边是number

==不像===那样严格,对于一般情况,只要值相等,就返回true,但==还涉及一些类型转换,它的转换规则如下

  • 两边的类型是否相同,相同的话就比较值的大小,例如1==2,返回false
  • 判断的是否是nullundefined,是的话就返回true
  • 判断的类型是否是StringNumber,是的话,把String类型转换成Number,再进行比较
  • 判断其中一方是否是Boolean,是的话就把Boolean转换成Number,再进行比较
  • 如果其中一方为Object,且另一方为StringNumber或者Symbol,会将Object转换成字符串,再进行比较
Last Updated:
Contributors: leeguooooo