上一期我们有讲到论如何让页面学会夸人这件事,在结尾我们有提到另一种学会夸人的方式,即实现以下代码
if(a === 1 && a === 2 && a === 3) {
console.log('作者真帅!')
}
有些人看过上一期,也许会想为什么不能继续使用对象的valueof或toString方法呢?
那么这又涉及到我的干货篇内容了,我们提到过==(双等)和===(三等)是有区别的,我在这就不一一赘述了,感兴趣的朋友可以去看一看
这次,我们主要要知道的一个点就是==(双等)具有隐式转换,但===(三等)没有隐式转换,且===(三等)会首先判断两边的数据类型
所以上次的方法就行不通了,那么咱们就继续讨论这道题,我看到的第一眼的想法是使用js代理(proxy),但试了好多次都没有成功,以下是我当时写的代码(有问题的版本)
let b = 0
let c = new Proxy(window, {
get(target, property) {
//这里原本的意思是想当每次进行window对象的读操作时,都会返回一个不同的值
return b++
}
})
let a = c.d //此次进行读操作后使a是从1开始进行比较,以为满足了条件
console.log(a)//0
console.log(a)//0
//多次打印结果都为0,无法判断成功
这时看完,也许有人能看出,a的变量是固定的,c.d只变化了一次,所以a无法满足条件,这时我有点不知所措,于是我就换了一种方法
这此使用的是数据劫持
var c = 1
Object.defineProperty(window, 'a', {
get() {
return this.c++
}
})
if (a === 1 && a === 2 && a === 3) {
console.log('作者真帅!') //这时会发现,页面又会夸人了
}
以上代码就是if判断实现的代码
这里正好讲解一下代理和劫持的区别
1.definePeoperty监听到的是对象中的某个属性,有很大的局限性;Proxy监听到的是某个对象
2.definePeoperty是劫持对象属性,Proxy是代理整个对象
3.definePeoperty会污染源对象,执行操作时会修改原属性;Proxy是对源对象进行代理并返回一个新的代理对象,并不会污染源对象
4.definePerperty不兼容IE8,Proxy不兼容IE11
以上劫持和代理的区别,仅是个人的理解
这里还有一个点,为什么会使用var呢,因为var会在window里去创建一个元素,但let声明的变量并不会在window里创建
这就是本次文章的主要内容了,如有错误或更好的写法可以私信或评论哦!