es6 proxy代理

es6 新增构造函数 Proxy

  Proxy 构造函数,可以使用new 去创建,可以往里面插入两个参数,都是对象

let target = {}
let handler = {}
let proxy = new Proxy(target,handler);
proxy.a = 'b'
console.log(proxy.a) //b

  上面代理拦截的操作handler 是个空对象所有不产生任何影响,target 代表时需要代理的哪个对象

  Proxy 一共可以代理拦截对象的13种操作

  1. get  当读取对象属性时触发 get 拦截一共可以传入三个参数 get(target,key,receiver) target 代表当前对象,key 当前属性名

  receiver 一般用不上,代表的是Proxy 对象

//常见的对象 get操作 代理
var handler = {
    get (target,key,receiver) {
        console.log(key);
        return `您想要的值是${target[key]}`
    }
}
var proxyy=new Proxy({},handler);
proxyy.xx=90;
console.log(proxyy.xx); //xx 您想要的值是90


//如果一个对象属性不可配置 且不可写,则不能使用proxy 访问此属性
var definedObject = Object.defineProperty({},'name',{
    writable:false,// 属性是否科协
    configurable:false,// 是否可重新配置
    value:'czcz' // 默认值
})
var prox = new Proxy(definedObject,handler);
prox.name;
//proxy.js:23 Uncaught TypeError: 'get' on proxy: 
//property 'name' is a read-only and non-configurable data property 
//on the proxy target but the proxy did not return its actual 
//value (expected 'czcz' but got '您想要的值是czcz')

  2.set set拦截一共可以传入四个参数 (target,key,value,receiver) 前三个参数必传,最后一个参数可选,以此代表,对象

  属性名,设置的属性值,Proxy 对象

// proxy 的set 方法,使用了set 一定要对target[key] 赋值要不会返回undefined
// 如下要是if条件过后 没有 target[key] = value 则 proz.age 最终会是undefined
var sethandler = {
    set (target,key,value,receiver) {
        if(key == 'name') {
            target[key] = `魔人的小妖精${value}`
            return
        }
        target[key] = value
    }
}
var proz = new Proxy({},sethandler);
proz.name = 'ljkkk';
proz.age = '18';
console.log(proz.name,proz.age) //魔人的小妖精ljkkk 18

//如果对象的属性描述是不可写,则不能使用proxy set 方法
var objsetfalse = Object.defineProperty({},'name',{
    value:'czcz',
    writable:false
})

var proc = new Proxy(objsetfalse,sethandler);
proc.name = 'lklk';
console.log(proc.name) //输出'czcz' 说明sethandler 里面的set操作无用

  3.apply   拦截对象的apply和call,和函数的调用 ,  apply一共可以传入三个参数 ,apply(target,ctx,args) ,目标对象,目标对象的上下文对象,参数数组

//apply 拦截函数的调用
var applyhandler = {
    apply (target,ctx,args) {
        console.log('apply',ctx,args)
    }
}
var fn = function () {
    console.log('xxccc');
}
var prolk = new Proxy(fn,applyhandler);
prolk(); // apply undefined [] 
//拦截 apply or call 操作
prolk.apply({},[1,3,4]); //apply {} (3) [1, 3, 4]
prolk.call(null,1,3,5); //apply null (3) [1, 3, 5]

  4.has 拦截hasProperty 操作判断对象是否具有某个属性是生效,has(target,key) 方法值传入连个参数, has 只有执行in 操 

  作时生效,但执行 for in 不生效(注如果某个属性不可配置或者该对象不可扩展则不能使用has拦截)

//has 属性的拦截
var hashandler = {
    has (target,key) {
        if(key === 'name') {
            return false
        }
        return true
    }
}
var prohas = new Proxy({},hashandler);
prohas.age = '18'
prohas.name = 'zc'
console.log('name' in prohas) //false
console.log('age' in prohas) // true

  5.construct 当使用new 去创建一个对象时进行拦截 construct(target,args,newtarget) 当前对象,参数,实例对象

var conhandler = {
    construct (target,args,newtarget) {
        console.log(target.args,newtarget)
        return new target(...args)
    }
}
var pp = new Proxy(function () {},conhandler)
new pp('1','2'); //undefined ƒ () { [native code] }
//传入的一定要是个构造函数 
 

猜你喜欢

转载自www.cnblogs.com/czkolve/p/10633510.html