我对js隐式转换终于不用再靠_猜_了!

2024 年 12 月 7 日 星期六(已编辑)
/ ,
6
这篇文章上次修改于 2024 年 12 月 11 日 星期三,可能部分内容已经不适用,如有疑问可询问作者。

我对js隐式转换终于不用再靠_猜_了!

一、前言

在项目开发或者面试中经常出现下面这种判断:

console.log({} - {})
console.log([] - [])
console.log([] + [1, 2])
console.log([] == ![])
console.log({} == {})

结果分别是:NaN、0、1,2、true、false

二、包装类

包装类是我们理解隐式转化的基础工具,是理解隐式转化的根基。

js中包装类分为:Boolean()、Number()、String()。

Boolean()

Boolean()只有两种值:truefalse

其中值为false的称为<font style="color:rgb(37, 41, 51);">falsey</font>虚值,分别包括0、null、undefined、false、'',NaN;

而值为`true`的称为`truth`,除了`falsey`其他的返回都是`true`

Number()

Number()的处理就分为对 基础类型 的处理和 引用类型 的处理。

基础类型

console.log(Number(null)) // 0
console.log(Number(undefined)) // MaM
console.log(Number('1')) // 1
console.log(Number('')) // 0
console.log(Number(NaN)) // NaN
console.log(Number('1ab') // NaN
console.log(Number(false)) // 0
console.log(Number(true)) // 1

其中为NaN的数值分别有undefinednull'1ab'

null表示"没有对象",即该处不应该有值。 undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。

'1ab'NaN是因为字符串转换中出现了非数字的就会转换成NaN

引用类型

假如我们现在有下面这么一个对象:

const obj = {
  toString() {
    return 2
  },
  valueOf() {
    return 1
  }
}

如果用Number()去取值的时候就会调用到valueOf()方法,此时会返回 1 ,但如果改写 valueOf() { return {} }的话就会去调用 toString(), 此时返回 2

所以Number(引用类型)的逻辑过程就是:

画板

画板

String()

String()就是跟Number()相反,先调用toString()然后再看valueOf()

const obj = {
    toString() {
      return {}
    },
    valueOf() {
      return 1    
    }
}
console.log(String(obj)) // 1
console.log(String({})) // [object Object]

3 < 2 < 1 和 2 < 1 < 1

两个输出都是true,第一个符合数学公式,第二个就涉及到隐式转换了

  1. 比较 2 < 1 结果为 fasle
  2. 现在就是 false < 1 ,Number(false) 为0
  3. 现在就是 0 < 1, 结果为 true

三、隐式转换规则

boolean 隐式转换触发

  1. if
  2. switch
  3. while
  4. for(;;)
  5. &&
  6. ||
  7. !
  8. !!
  9. ? : 三元运算

number 隐式转换触发

用到数字运算符的地方都会进行转换:+ - * / == ~~ & | ~ ^ << <<<

string 隐式转换触发

+ 且两边大于等于1个string类型. 除了有 symbol类型之外

console.log(1 + '2' + '2') // '122'
console.log(1 + + '2' + '2') // '32'
console.log('A' - 'B' + '2') // 'NaN2'
console.log('A' - 'B' + 2) // NaN
  1. 用 + 包裹,全部就转换为字符串后相加操作
  2. +'2' 会先进行 number 转换,变成1 + 2 = 3,然后遇到 + 在进行string转换
  3. 'A' - 'B' 会先进行 number 转换,变成 NaN,然后string转换
  4. 同上

四、需要注意的点

console.log((123).toString()) // 123
console.log(undefined.toString()) // 报错
console.log(null.toString()) // 报错

undefinednull并没有包装类,它们是基础类型,所以没有toString()方法

五、面试题

console.log([] == ![]) // true
  1. 一看到 == 就会想到两边会进行 Number转换
  2. Number([]) 会调用到 Array.prototype.toSting(),得到的是一个空字符串 '' ,用Number转换后就会变成0
  3. 右边 ![]会先进行 Boolean 转换,[] 不是 falsey,所以Boolean([])true
  4. !true 再进行Numebr 转换就会变成 0
  5. 所以最终就是0 == 0,结果为true

六、奇奇怪怪的题目

66.toString() // 报错: Invalid or unexpected token
66..toString() // '66'
66.6.toString() // '66.6'
66...toString() // 报错: Unexpected token '.'

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...