JS 对象劫持

2019-03-21  本文已影响0人  木安小学生

对象劫持

在目标对象之前加一层"拦截",外界对该对象的访问,都必须先通过这层拦截,对此,提供了一种机制,可以对外界的访问进行过滤和改写。这种机制就称对象劫街持。

Object.prototype.valueOf

在 通过 字面量 访问一个对象obj时 是 默认得到的是 obj.valueOf

var a ={
  b:1,
  valueOf(){
    return this.b++
  }
}
if(a==1&&a==2&&a==3){
  console.log('执行')
}

可以看到,每次访问 对象 a 时 都 进入了 a.valueOf 方法,使的 每次返回的值 都自增一次,逐次满足 if 判断 打印出 “执行”

Object.defineProperty(obj,prop,descriptor)

会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

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 标识该属性可被修改和删除
})

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'

从打印结果来看,就是在访问和写入 b 属性 时 劫持并重定义对象的getter和setter方法进行自定义返回

ECMAScript6新增了一个更加方便和完善的特性Proxy

ECMAScript6新增了一个特性Proxy。Proxy可以用来拦截某个对象的属性访问的方法,然后重载对象的"."运算符。

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"
上一篇下一篇

猜你喜欢

热点阅读