Proxy
Proxy用于修改某些操作的默认行为,等同于在语言层面作出修改,所以属于一种“元编程”,即对编程语言进行编程
ES6原生提供Proxy构造函数,用来生成Proxy实例
var proxy = newProxy(target,handler);
new Proxy()表示生成一个Proxy实例。target参数是索要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为
注意,要使得Proxy起作用,必须针对Proxy实例进行操作,而不是针对目标对象。
如果handler没有设置任何拦截,那就等同于直接通向原对象
下面是Proxy支持的拦截操作一览,对于可以设置、但没有设置拦截的操作,则直接落在目标对象上,按照原先的方式产生结果
1)get(target、propKey、receiver)
拦截对象属性的读取,比如proxy.foo和proxy['foo']
2)set(target、propKey、value、receiver)
拦截对象属性的设置
3)has(target,proKey)
拦截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(taget,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 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
(13)construct(target, args)
拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
Proxy实例的方法
get()方法用于拦截某个属性的读取操作。
3、Proxy.revocable()
Proxy.revocable方法返回一个可取消的Proxy实例
4、this问题
5、实例web服务的客户端
Reflect
1)reflect对象与Proxy对象一样,也是ES6为了操作对象而提供的心API
2)静态方法,大部分与object对象的同名方法的作用都是相同,而且它与Proxy对象的方法是一一对应的。
3)Reflect.apply(target,thisArg,args) 这个方法等同于Function.prototype.apply.call(funnc,thisArg,args),用于绑定this对象对象后执行给定函数
4)Reflect.construct(target,args) 这个方法等同于new target(...args),这提供了一种不使用new来吊桶构造函数的方法
5)Reflect.get(target,name,receiver)查找并返回target对象的name属性,如果没有该属性,则返回undefined。如果第一个参数不是对象,Reflect.get方法会报错
6)Reflect.set(target,name,value,receiver) Reflect.set方法设置target对象的name属性等于value
Reflect.set与Reflect.get一样,如果第一个参数不是对象,它会报错
注意Reflect.set会出发Proxy.defineProperty拦截
7)Reflect.defineProperty(target,name,desc) 这个方法等用于Object.defineProperty,用来为对象定义属性。未来后者被逐渐剔除
8)Reflect.deleteProperty(target,name) 用于删除对象的属性 等同于 delete obj[name]
9)Reflect.has(target,name) 对应name in obj里面的in运算符
Reflect.ownKeys(target) 基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。
Reflect.isExtensible(target) 这个方法对应Object.preventExtensions方法,用于让一个对象编程不可扩展。它返回一个布尔值,表示是否操作成功
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name) 这个方法等同于Object.getOwnPropertyDescriptor用于得到指定属性的描述对象
Reflect.getPrototypeOf(target) 用于读取对象的_proto_属性,对应Object.getPrototypeof(obj)
Reflect.getPrototypeOf和Object.getPrototypeof的一个区别是,如果参数不是对象,Object.getProrypeOf会将这个参数转为对象,然后再运行,但是Reflect.getPrototypeof会报错
Reflect.setPrototypeOf(target, prototype) 用于设置对象的_proto_属性,返回第一个参数对象,对应Object.setPrototypefOf(obj)