對象劫持
在目標(biāo)對象之前加一層"攔截"颗圣,外界對該對象的訪問芥备,都必須先通過這層攔截履婉,對此程癌,提供了一種機(jī)制嘴瓤,可以對外界的訪問進(jìn)行過濾和改寫扫外。這種機(jī)制就稱對象劫街持。
Object.prototype.valueOf
在 通過 字面量 訪問一個(gè)對象obj時(shí) 是 默認(rèn)得到的是 obj.valueOf
var a ={
b:1,
valueOf(){
return this.b++
}
}
if(a==1&&a==2&&a==3){
console.log('執(zhí)行')
}
可以看到廓脆,每次訪問 對象 a 時(shí) 都 進(jìn)入了 a.valueOf 方法筛谚,使的 每次返回的值 都自增一次,逐次滿足 if 判斷 打印出 “執(zhí)行”
Object.defineProperty(obj,prop,descriptor)
會(huì)直接在一個(gè)對象上定義一個(gè)新屬性停忿,或者修改一個(gè)對象的現(xiàn)有屬性驾讲, 并返回這個(gè)對象。
let obj = {name:'Joe',age:100}
let bValue
Object.defineProperty(obj,'b',{
get:function(){
console.log('get b')
return bValue
},
set:function(newValue){
bValue = newValue
console.log('set b')
},
enumerable:true, //為 true 表示 該屬性 可被枚舉
configurable:true //為true 標(biāo)識該屬性可被修改和刪除
})
console.log(obj) // {name:'Joe',age:100,b:undefined}
console.log(obj.b) // 'get b' undefined
obj.b = "dollar" // 'set b'
console.log(obj.b) // 'dollar'
從打印結(jié)果來看,就是在訪問和寫入 b 屬性 時(shí) 劫持并重定義對象的getter和setter方法進(jìn)行自定義返回
ECMAScript6新增了一個(gè)更加方便和完善的特性Proxy
ECMAScript6新增了一個(gè)特性Proxy吮铭。Proxy可以用來攔截某個(gè)對象的屬性訪問的方法时迫,然后重載對象的"."運(yùn)算符。
let obj = {name:'Joe',age:100}
let obj1 = new Proxy(obj,{
get:function(target,key,receiver){
console.log(`get ${key}`)
return Reflect.get(target,key,receiver)
},
set:function(target,key,value,receiver){
console.log(`set ${key}`)
return Reflect.set(target,key,value,receiver)
}
})
console.log(obj1.name) // get name "Joe"
obj1.name="Bob" // set name
console.log(obj1.name) // get name "Bob"