让 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 | } |
参考链接