废话少说,我们直接上代码
1. 使用 toString方法
var a = {i: 1 ,toString(){return a.i++;}}
if(a == 1 && a == 2 && a==3){
alert(“a=1,a=2,a=3条件成立”)
}
如果原始类型的值和对象比较,对象会转为原始类型的值,再进行比较
2.使用 valueOf
a.valueOf=function(){reutrn this.num+=1}
if(a1&&a2&a==3){
alert(“a=1,a=2,a=3条件成立”)
}
a == 1 =>
a.valueOf() ==1 =>
a.num += 1 ==1 =>
0 += 1 ==1 =>
1 == 1 => true
a == 2 =>
a.valueOf() == 2 =>
a.num += 1 == 2 =>
1 += 1 == 2 =>
2 == 2 => true
a == 3 =>
a.valueOf() == 3 =>
a.num += 1 == 3 =>
2 += 1 == 3 =>
3 == 3 => true
3.使用数组
var a = [1, 2, 3];
a.join = a.shift;
if(a==1&&a==2&a==3){
alert("a=1,a=2,a=3条件成立")
}
可以看到数组 toString 会调用本身的 join 方法,
这里把自己的join方法该写为shift,每次返回第一个元素,
而且原数组删除第一个值,正好可以使判断成立。这里 == 比较也带来的副作用,
==比较的时候类型不一样会转换类型,
Object类型会调用toString,array调用join,number调用valueOf,
答案为重写Object的toString的方式。
4. 原始数据类型Symbol
let a = {[Symbol.toPrimitive]: ((i) => () => ++i) (0)};
if(a1&&a2&a==3){
alert(“a=1,a=2,a=3条件成立”)
}
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。
我们之前在定义类的内部私有属性时候习惯用 __xxx ,这种命名方式避免别人定义相同的属 性名覆盖原来的属性,
有了 Symbol 之后我们完全可以用 Symbol值来代替这种方法,而且完全不用担心被覆盖。
5.利用with 关键字
var i = 0;
with({
get a() { 每次调用a读取 i的值
return ++i;
}
})
if(a1&&a2&a==3){
alert(“a=1,a=2,a=3条件成立”)
}
with 也是被严重建议不使用的对象,这里也是利用它的特性在代码块里面利用对象的 get 方法动态返回 i
6.使用Object.defineProperty()
var val=0;
object.defineProperty(window,‘a’,{
get:function(){
return ++val;
}
});
if(a1&&a2&a==3){
alert(“a=1,a=2,a=3条件成立”)
}
我们知道我们用的全局变量也相当于 window 对象上的一个属性,
这里用defineProperty 定义了 a的 get 也使得其动态返回值。和with 有一些类似。
好了,本次介绍a1&&a2&&a==3就结束了。