Proxy用于修改某些操作的默认行为,等同于在语言层面作做出修改,
所以属于一种元编程,即对编程语言进行编程
Proxy可以理解成在目标对象前架设一个"拦截"层,
外界对该对象的访问都必须先通过这层拦截,
因此提供了一种机制可以对外界的访问进行过滤和改写。
Proxy这个词原意是代理,在这里表示"代理"某些操作,可以译为"代理器"
const {
get , set } = Reflect;
let obj = new Proxy({
},{
get : function(target,key,receiver){
console.log(`getting ${
key}!`);
return get(target,key,receiver);
},
set : function(target,key,value,receiver){
console.log(`setting ${
key}!`);
return set(target,key,value,receiver);
}
});
obj.count = 1;
++obj.count;
Proxy实际上重载了点运算符,即用自己的定义覆盖了语言的原始定义
ES6原生提供Proxy构造函数,用于生成Proxy实例
let proxy = new Proxy(target,handler);
target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为
一个例子:
let proxy2 = new Proxy({
},{
get : function(target,property){
return 35;
}
})
console.log(proxy2.time);
console.log(proxy2.name);
将Proxy对象设置到object.proxy属性,从而可以在object对象上调用
let [target , handler] = [{
},{
}];
let object = {
proxy: new Proxy(target,handler) };
let {
create , prototype } = Object;
Proxy也可以作为其他对象的原型对象
let proxy3 = new Proxy({
},{
get : function(target,handler){
return 45;
}
})
let obj2 =create(proxy3);
console.log(obj2.time);
这段代码中,proxy3对象是obj对象的原型
obj对象本身没有time属性,所以根据原型链会在proxy3对象上读取该属性,导致被拦截
同一个拦截器函数可以设置拦截多个操作:
let handler2 = {
get : function(target,name){
if(name === 'prototype'){
return prototype;
}
return 'hello, ' + name;
},
apply : function(target,thisBinding,args){
return args[0];
},
construct : function(target,args){
return {
value : args[1]
};
}
};
let fproxy = new Proxy(function(x,y) {
return x + y;
},handler2);
console.log(fproxy(1,2));
// console.log(new fproxy(1,2));
console.log(fproxy.foo);
// console.log(fproxy.prototype === prototype);
Proxy支持的拦截操作
1.get(target,propKey,receiver) 拦截对象属性的获取
2.set(target,propKey,value,receiver) 拦截对象属性的设置
3.has(target,propKey) 拦截propKey in proxy操作
4.deleteProxy(target,propKey) 拦截delete proxy[propKey]操作
5.ownKey(target) PS:Object.key()返回结果仅包括对象自身可遍历属性
6.getOwnPropertyDescriptor(target,propKey)
7.defineProperty(target,propKey,propDesc)
8.preventExtensions(target)
9.getPrototypeOf(target)
10.isExtensible(target)
11.setPrototype(target,proto)
12.apply(target,object,args) 拦截proxy实例,并将其作为函数调用的操作
13.construct(target,args) 拦截Proxy实例作为构造函数调用的操作