左小白的技术日常
Github
2020/08/22
Author: guoqzuo

什么情况下 a == 1 && a == 2,什么情况 a + 1 === a + 2

在js面试时,有时候会考察 ==(比较运算符)隐式转换的问题,问 a == 1 && a == 2 怎么使他成立,这个有好几种方法。还有一种情况下 a + 1 全等于 a + 2,这就涉及到最大安全整数的问题了,下面来具体看看

什么情况下a == 1 && a == 2为true

有两种方法可以实现,一是使用对象隐式转换的方法,二是使用对象的defineProperty定义get访问器属性

对象的toString或valueOf方法

对象与数字比较,转字符串比较,会调用对象的toString/valueOf方法,把toString或valueOf函数处理下即可,在chrome浏览器的console里,两种函数都可以

var a = { 
  count: 1, 
  toString() { 
    return this.count++ 
  }
}
a == 1 && a == 2 // true
var a = { 
  count: 1, 
  valueOf() { 
    return this.count++ 
  }
}

使用Object.defineProperty设置get访问器属性

可以为对象定义访问器属性(get),访问该对象的属性时,就会直接调用get函数,在get函数做一些处理也可以实现

var a = {
  count: 1
}
Object.defineProperty(a, 'prop', {
  get() {
    return this.count++
  }
})
a.prop == 1 && a.prop == 2

参考:js面试题:a==1&&a==2&&a=3的两个思路

a + 1 === a + 2 为true的情况,注意是全等

注意这里是全等。我现在了解的有两种情况:Infinity、或最大安全整数Number.MAX_SAFE_INTEGER

// 1. Infinity
var a = Infinity // Infinity是这个神奇的数,我试了下除了 * 0等于NAN外,其他情况基本都等于他自己
a + 1 === a + 2 // true

// 2. Math.pow(2, 53) - 1 最大的安全整数
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) -1 // true
a = Number.MAX_SAFE_INTEGER
a + 1 === a + 2 // true

以上,当大于2的53次方-1时,就不安全了,结果会超出常规,ES2020引入了bigint来处理大于2的53次方-1的数据

// bigint类型的数与n结尾
a = BigInt(Number.MAX_SAFE_INTEGER) // 9007199254740991n
a + 1n // 9007199254740992n
a + 2n // 9007199254740993n

参考:ES2020 bigint数据类型,为什么要新增这个数据类型?