再次遇到这个问题,记录下来js
一.利用不同数据类型之间的比较时隐式转换 (对象类型转换)
例一
var a = {
i:1,
valueOf:function(){ // toString效果一样
return a.i++;
}
}
console.log(a==1,a==2,a==3)// true true true
原理:
复杂数据类型([],{})在与number进行运算时 隐式转换会先转成String,然后再转成Number运算。如:
[].valueOf().toString() == '' || {}.valueOf().toString() == '[object Object]'
Number('') == 0 || Number('[object Object]') = NaN
此处改变了对象的valueOf方法或是toString方法,让对象每次调用时返回一个 ++的值
例二
var a = [1,2,3];
a.join = a.shift;
console.log(a==1,a==2,a==3)// true true true
原理:
与上面这个类型转换一样,数组调用toString()会调用Array.join()方法 而数组shift方法的用法:shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。如果数组是空的,那么 shift() 方法将不进行任何操作,返回 undefined 值。请注意,该方法不创建新数组,而是直接修改原有的 arrayObject。 所以我们可以看到 a==1时会调用toString(),toString()调用join(),join等同于shift,则转换为Number类型后为1
二.通过改变获取a的getter方法(Object.defineProperty)
Object.defineProperty(obj, prop, desc) // 1.需要定义属性的当前对象 2.需要定义的属性名 3.属性的描述
var value = 0
Object.defineProperty(window,'a',{
get(){
return value+=1;
}
})
console.log(a==1,a==2,a==3)// true true true