ES6学习笔记四:Proxy与Reflect

一:Proxy

代理。

ES6把代理模式做成了一个类,直接传入被代理对象、代理函数,即可创建一个代理对象,然后我们使用代理对象进行方法调用,即可调用被包装过的方法:

1)创建

var proxy = new Proxy(target, handler);

new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为,其中定义了一系列的代理方法。

如果handler没有设置任何拦截,那就等同于直接通向原对象。

2)handler中定义的拦截操作主要有:

1)get(target, propKey, receiver)

拦截对象属性的读取,比如proxy.fooproxy['foo']

最后一个参数receiver是一个对象,可选,参见下面Reflect.get的部分。

(2)set(target, propKey, value, receiver)

拦截对象属性的设置,比如proxy.foo = vproxy['foo'] = v,返回一个布尔值。

(3)has(target, propKey)

拦截propKey in proxy的操作,返回一个布尔值。

(4)deleteProperty(target, propKey)

拦截delete proxy[propKey]的操作,返回一个布尔值。

(5)ownKeys(target)

拦截Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。

(6)getOwnPropertyDescriptor(target, propKey)

拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。

(7)defineProperty(target, propKey, propDesc)

拦截Object.defineProperty(proxy, propKey, propDesc)Object.defineProperties(proxy, propDescs),返回一个布尔值。

(8)preventExtensions(target)

拦截Object.preventExtensions(proxy),返回一个布尔值。

(9)getPrototypeOf(target)

拦截Object.getPrototypeOf(proxy),返回一个对象。

(10)isExtensible(target)

拦截Object.isExtensible(proxy),返回一个布尔值。

(11)setPrototypeOf(target, proto)

拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。

如果目标对象是函数,那么还有两种额外操作可以拦截。

(12)apply(target, object, args)

拦截 Proxy 实例作为函数调用的操作,callapply操作。,比如proxy(...args)proxy.call(object, ...args)proxy.apply(...)

(13)construct(target, args)

拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)

二:Reflect

Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。

说白了,Reflect.XX 就是被代理的方法。

我们在proxy中使用Reflect.XX调用原本要调用的操作,然后在此前后定义一些代理操作,就形成了代理方法

var loggedObj = new Proxy(obj, {
get(target, name) {
console.log('get', target, name);
return Reflect.get(target, name);//调用对target对象的原本操作
},
deleteProperty(target, name) {
console.log('delete' + name);
return Reflect.deleteProperty(target, name);
},
has(target, name) {
console.log('has' + name);
return Reflect.has(target, name);
}
});

Reflect可调用的方法:

  • Reflect.apply(target,thisArg,args):
  • Reflect.construct(target,args)
  • Reflect.get(target,name,receiver)
  • Reflect.set(target,name,value,receiver)
  • Reflect.defineProperty(target,name,desc)
  • Reflect.deleteProperty(target,name)
  • Reflect.has(target,name)
  • Reflect.ownKeys(target)
  • Reflect.isExtensible(target)
  • Reflect.preventExtensions(target)
  • Reflect.getOwnPropertyDescriptor(target, name)
  • Reflect.getPrototypeOf(target)
  • Reflect.setPrototypeOf(target, prototype)
上一篇:13个JavaScript图表(JS图表)图形绘制插件【转】


下一篇:IOS Socket 04-利用框架CocoaAsyncSocket实现客户端/服务器端