Proxy 用于修改某些操做的默认行为,等同于在语言层面作出修改,因此属于一种“元编程”(meta programming),即对编程语言进行编程。编程
Proxy 能够理解成,在目标对象以前架设一层“拦截”,外界对该对象的访问,都必须先经过这层拦截,所以提供了一种机制,能够对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操做,能够译为“代理器”。bash
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
复制代码
上面代码对一个空对象架设了一层拦截,重定义了属性的读取(get
)和设置(set
)行为。这里暂时先不解释具体的语法,只看运行结果。对设置了拦截行为的对象obj
,去读写它的属性,就会获得下面的结果。
编程语言
obj.count = 1
// setting count!
++obj.count
// getting count!
// setting count!
// 2复制代码
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。函数
var proxy = new Proxy(target, handler);复制代码
Proxy 对象的全部用法,都是上面这种形式,不一样的只是handler
参数的写法。其中,new Proxy()
表示生成一个Proxy
实例,target
参数表示所要拦截的目标对象,handler
参数也是一个对象,用来定制拦截行为。
ui
var proxy = new Proxy({}, {
get: function(target, property) {
return 35;
}
});
proxy.time // 35
proxy.name // 35
proxy.title // 35复制代码
一、将Object
对象的一些明显属于语言内部的方法(好比Object.defineProperty
),放到Reflect
对象上。现阶段,某些方法同时在Object
和Reflect
对象上部署,将来的新方法将只部署在Reflect
对象上。也就是说,从Reflect
对象上能够拿到语言内部的方法。spa
二、修改某些Object
方法的返回结果,让其变得更合理。好比,Object.defineProperty(obj, name, desc)
在没法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)
则会返回false
。代理
三、让Object
操做都变成函数行为。某些Object
操做是命令式,好比name in obj
和delete obj[name]
,而Reflect.has(obj, name)
和Reflect.deleteProperty(obj, name)
让它们变成了函数行为。code
四、Reflect
对象的方法与Proxy
对象的方法一一对应,只要是Proxy
对象的方法,就能在Reflect
对象上找到对应的方法。这就让Proxy
对象能够方便地调用对应的Reflect
方法,完成默认行为,做为修改行为的基础。也就是说,无论Proxy
怎么修改默认行为,你总能够在Reflect
上获取默认行为。对象
Proxy(target, {
set: function(target, name, value, receiver) {
var success = Reflect.set(target,name, value, receiver);
if (success) {
log('property ' + name + ' on ' + target + ' set to ' + value);
}
return success;
}
});
复制代码
上面代码中,Proxy
方法拦截target
对象的属性赋值行为。它采用Reflect.set
方法将值赋值给对象的属性,确保完成原有的行为,而后再部署额外的功能。
部署