欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于如何使`(a === 1 && a === 2 && a === 3)`返回`true`问题的思考

程序员文章站 2022-07-06 12:02:41
看见这个面试题目,第一反应就是在变量 取值时进行了一些改变,那就要用 ,关于存取器的介绍可以看 "这里" 同样的问题是使 返回 ,不同点是,这里是 ,而不再是 。 恒等运算符在比较过程中, 不会有任何类型转换 ; 相等运算符比较宽松,如果两个操作数不是同一类型,那么 相等运算符会尝试进行一些类型转换 ......

看见这个面试题目,第一反应就是在变量a取值时进行了一些改变,那就要用getter,关于存取器的介绍可以看这里

var temp = 1;
object.defineproperty(window, 'a', {
    get: function() { // 每次取值,temp+1
        return this.temp++
    }
});

console.log( a === 1 && a === 2 && a === 3); // true
console.log(a) // 4

同样的问题是使 (a == 1 && a == 2 && a == 3) 返回true,不同点是,这里是==,而不再是===

===恒等运算符在比较过程中,不会有任何类型转换
==相等运算符比较宽松,如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较。转换规则如下:

  1. 如果一个是null,一个是undefined,则它们相等
  2. 如果一个是数字,一个是字符串,先将字符串转换成数字,然后使用转换后的值进行比较
  3. 如果其中的一个值为true,则转换成1再进行比较;如果其中一个值为false,这转换成0再进行比较
  4. 如果一个值是对象,另一个值是数字或者字符串,则将对象转换成原始值再进行比较。转换成字符串时,会先调用tostring(),如果没有tostring()方法或者返回的不是一个原始值,则再调用valueof(),如果还是不存在或者返回不是原始值,则会抛出一个类型错误的异常。返回的原始值会被转换成字符串;如果转换成数字时,也是类似的,不过是会先调用valueof(),再调用tostring(),返回的原始值会被转换成数字
  5. 其他不同类型之间的比较均不相等

更详细的数据类型转换可以看 这里

回到题目中,除了第一种使用getter的思路外,可以将a作为一个对象,而它的在比较中会转换成数字,所以可以重写valueof()方法,在每次取值的时候,进行一些处理。

let a = {
    temp:1,
    valueof:function(){
        return this.temp++
    }
}

console.log(a == 1 && a == 2 && a == 3); // true
console.log(a) {temp:4,valueof: f ()}

以上是关于这个问题的两种思路,当然还有还有我不知道的其他的做法,以后再补充