【每日面试题】 实现 a == 1 & a == 2 & a == 3 返回 true

317 阅读1分钟

📅 2021 / 03 / 26

1. 对象类型转换

var a = {
    value: 1,
    toString: function () {
        return a.value++;
    }
};

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

var a = {
    value: 1,
    valueOf: function () {
        return a.value++;
    }
}

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

原理:Object 类型与 Number 类型比较时,会将 Object 类型转换为 Number 类型。转换时会尝试调用 Object.valueOf 和 Object.toString 来获取对应的数字基本类型。重写 toString 方法或者 valueOf 方法都可以实现该效果。

2. 数组类型转换

var a = [1, 2, 3];

a.join = a.shift;

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

原理:数组的 toString 会隐含调用 Array.join 方法。数组的 shift 方法会将数组中第一个元素删除,并返回该元素的值。所以我们看到 a == 1 时,会调用 join 方法,因为 join 方法被重写为 shift 方法,所以转换为 Number 后为 1。

3. 定义属性 “a”,并重写 getter 方法,严格模式下同样适用

var val = 0;
Object.defineProperty(window, 'a', {
    get: function() {
        return ++val;
    }
})

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

4. 实例化

function A () {
	var value = 0;
  this.valueOf = function () {
  	return ++value;
  }
}

var a = new A();

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

// ES6 版本
class A {
    constroctar() {
        this.value = 0;
        this.valueOf()
    }
  
    valueOf() {
        return this.value++;
    }
}

var a = new A();

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