让 a == 1 && a == 2 && a == 3 输出 true

方案一 toString

1
// 对象转换成原始类型的值,算法是先调用valueOf方法;如果返回的还是对象,再接着调用toString方法
2
3
var a = {
4
  value: 1,
5
  toString() {
6
    return a.value++;
7
  }
8
};
9
10
console.log(a == 1 && a == 2 && a == 3);

方案二 valueOf

1
// 对象转换成原始类型的值,算法是先调用valueOf方法;如果返回的还是对象,再接着调用toString方法
2
3
var a = {
4
  value: 1,
5
  valueOf() {
6
    return a.value++;
7
  }
8
};
9
10
console.log(a == 1 && a == 2 && a == 3);

方案三 es6 的 Symbol.toPrimitive

1
// Symbol.toPrimitive相比 toString 和 valueOf。Symbol.toPrimitive 方法在转换基本类型的时候优先级最高。
2
var a = {
3
  [Symbol.toPrimitive]: (function(hint) {
4
    var i = 1;
5
    return function() {
6
      return i++;
7
    };
8
  })()
9
};
10
11
console.log(a == 1 && a == 2 && a == 3);

方案四 重写数组的 join 方法

1
// 数组在转换基本类型的时候toString 接口默认调用数组的 join 方法,重写数组的 join 方法。
2
var a = [1, 2, 3];
3
a.join = a.shift;
4
// a.toString = a.shift;  // 直接改写数组的toString方法也可以
5
6
console.log(a == 1 && a == 2 && a == 3);

方案五 Object.defineProperty

1
// node环境下是global,浏览器环境把global换成window
2
3
Object.defineProperty(global, "a", {
4
  get() {
5
    return (this.value = this.value ? (this.value += 1) : 1);
6
  }
7
});
8
9
console.log(a == 1 && a == 2 && a == 3);

方案六 es6 的 Reflect.defineProperty

1
// Reflect.defineProperty类似于Object.defineProperty
2
3
// node环境下是global,浏览器环境把global换成window
4
5
Reflect.defineProperty(global, "a", {
6
  get() {
7
    return (this.value = this.value ? (this.value += 1) : 1);
8
  }
9
});
10
11
console.log(a == 1 && a == 2 && a == 3);

方案七 es6 的 Proxy 代理

1
var a = new Proxy(
2
  {},
3
  {
4
    i: 1,
5
    get: function() {
6
      return () => this.i++;
7
    }
8
  }
9
);
10
11
console.log(a == 1 && a == 2 && a == 3);

方案八 正则替换

1
// 方案八 reg
2
var a = {
3
  reg: /\d/g,
4
  valueOf() {
5
    return this.reg.exec(123)[0];
6
  }
7
};
8
9
console.log(a == 1 && a == 2 && a == 3);

方案九 利用 with 关键字(不建议使用)

1
var i = 0;
2
with ({
3
  get a() {
4
    return ++i;
5
  }
6
}) {
7
  console.log(a == 1 && a == 2 && a == 3);
8
}

参考链接

  1. https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/57
  2. https://m.toutiaocdn.com/group/6695747520343048712/?app=news_article_lite&timestamp=1570594235&req_id=201910091210350100200470140E129E3A&group_id=6695747520343048712