Proxy 用于修改某些操作的默认行为
(基本操作有属性查找,赋值,枚举,函数调用等)。
/** target 目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)* handler 一个对象,其属性是操作对应的自定义代理函数*/let p = new Proxy(target, handler);
基本操作
1、get(target, propKey, receiver):拦截对象属性的读取
/** target 目标对象* propKey 对象属性名* proxy 实例本身(严格地说,是操作行为所针对的对象)*/get(target, propKey, receiver)
var obj = {name : 'Lucy'}var p = new Proxy(obj,{ get : function(target,key,receive){ return key === 'name' ? 'Hello '+target[key] : target[key] }})p.name //Hello Lucy
需要注意的是,如果一个属性不可配置(configurable)且不可写(writable),则 Proxy 不能修改该属性。
var obj = Object.defineProperties({}, { name: { value: 'Lucy', writable: false, configurable: false },});var p = new Proxy(obj, { get : function(target,key){ return key === 'name' ? 'Hello '+target[key] : target[key] }});p.name //报错
2、set: function(obj, prop, value,receive) : 拦截某个属性的赋值操作
/** target 目标对象* key 属性名* value 属性值* receive 代理本身*/set: function(target, key, value,receive)
var obj = {age : 18}var p = new Proxy(obj,{ set : function(target,key,value){ if(key === 'age'){ target[key] = Math.min(value,100); }else{ target[key] = value; } }})p.age = 101;p.age // 100obj.age // 100
3、has(target, key):拦截key in proxy的操作,返回一个布尔值。
4、deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
5、ownKeys(target):ownKeys方法用来拦截对象自身属性的读取操作,返回一个数组。具体来说,拦截以下操作:
Object.getOwnPropertyNames()
//返回所有属性Object.getOwnPropertySymbols()
Object.keys(proxy)
//返回可枚举属性for...in
循环
var obj = Object.create(null)Object.defineProperties(obj, { '_id': { value: 1, configurable : true, writable : true, enumerable : true }, 'name': { value : 'Lucy', configurable : true, writable : true, enumerable : true }});Object.getOwnPropertyNames(obj) // ['_id','name']for(let key in obj){ console.log(key) //依次输出_id,name}var p = new Proxy(obj,{ ownKeys : function(target){ return Object.getOwnPropertyNames(target).filter(x => x[0] != '_') }})Object.getOwnPropertyNames(p) // ['name']for(let key in p){ console.log(key) //输出name}
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 实例作为函数调用的操作,比如
proxy(...args)
proxy.call(object, ...args)
proxy.apply(...)
13、construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
参考资料:
Proxy MDN
ECMAScript 6入门