美文网首页
JS 对象劫持

JS 对象劫持

作者: 木安小学生 | 来源:发表于2019-03-21 11:45 被阅读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"
    

    相关文章

      网友评论

          本文标题:JS 对象劫持

          本文链接:https://www.haomeiwen.com/subject/orlqvqtx.html