Es6 玩转proxy代理

165 阅读2分钟

是什么 ?

代理 可以取 (数组、对象、函数、等)

有什么作用 ?

1.接口的拦截器
2.表单校验拦截器
3.封装插件可以用  等等

怎么用? var ar = new Proxy(target,handler) //写法像 之前是构造函数 target :目标对象 handler: 拦截器 一个对象 (起到过滤对象的作用 的对象)

支持拦截get

拦截我们读取对象某个属性的拦截
例子:
let person = {
    name:'王五'
}
let person = new Proxy(person,{
    get:function(target,property){ // 目标对象  对象属性名   Proxy 属性名 
        console.log(target,property)
        if(property in  target){
            return target[property]
        }else{
            属性不存在
        }
    }
})
person.name // {  name:'王五'}  ,  name
// 判断这个属性对象 是否在这个上

throw 抛出错误
throw new MyException("除数不能是负数"); // 异常信息 

支持set拦截

// person对象有一个age属性 要求age不大于100
// age一定是个整数

let person = new Proxy({},{
    set:function(target,prop,value){ // 
        if(prop === 'age'){ // 目标对象  属性名 属性值 实例
            if(!Number.isInteger(value)){
                console.log('年龄不是整数');
            }
            if(value > 150){
                console.log('超出最大年龄');
            }
        }
        // 满足条件的直接保存
        target[prop] = value
    }
})

// person = {}
person.age = 300

person.age = '300'

get set综合实例 需求:属性是_不能被外界访问 如果访问抛出错误 拦截器

let person = new Proxy({},{
    get:function(target,key){
         inver(key,'get')
        return target[key]
    },
    set:function(target,key,value){
        inver(key,'set')
        target[key] = value
    }
})
function inver(key,action){
    if(key[0] === '_'){
        throw new Error('内部属性禁止访问')
    }
}
  proxy._prop = 'c' //  内部属性禁止访问

拦截对象删除的操作(deleteProperty)

 let proxy = new Proxy({name:'张三'},{
    deleteProperty(target,key){
 
         delete target[key]
    }
})
delete proxy.name  // 空的proxy:{}
console.log(proxy);

案例

  1. 不让其他开发者删除 noDelete这个属性
  2. 让调用 oldMethod 的开发者了解到这个方法已经废弃了
  3. 让开发者不要修改 doNotChange 属性
let dataStore  = {
    noDelete:'我不能删除',
    oldMethod:function(a,b){
        console.log(a+b);
        
    },
    doNotChange:'不能改变'
}
const NODELETE = ['noDelete']
const NOCHANGE = ['doNotChange']
const DEPRECATED = ['oldMethod']
dataStore = new Proxy(dataStore,{
    set(target,key,value){
        if(NOCHANGE.includes(key)){
            throw Error('不能改变')
        }
    },
    deleteProperty(target,key){
        if(NODELETE.includes(key)){
            throw Error('不能删除')
        }
    },
    get(target,key){
        if(DEPRECATED.includes(key)){
            console.warn('方法已经舍弃')
        }
        return target[key]
    }
})
// dataStore.doNotChange = '123'
// delete dataStore.noDelete
dataStore.oldMethod(1,3)