Proxy
作者:互联网
一.原意为代理
修改某些操作的默认行为,在目标对象前架设一层拦截,外界对对象的访问都必须先通过这层的拦截,对外界的访问进行过滤和改写
let 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); } }) obj.count = 1 // setting count!</br> ++obj.count // getting count!</br> // setting count!</br>
二..基础语法
Proxy接受两个参数
第一个参数是所要代理的目标对象(上例是一个空对象),即如果没有Proxy的介入,操作原来要访问的就是这个对象;
第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作
let handler={ get:function (target,name) { if(name==='prototype'){ return Object.prototype } return'hello, '+name; }, apply:function (target,thisBingding,args) { debugger return args[0]; }, construct:function (target,args) { return {value:args[1]} } } let fproxy=new Proxy(function (x,y) { return x+y; },handler); fproxy(1, 2) // 1 调用apply new fproxy(1, 2) // {value: 2} 调用construct fproxy.prototype === Object.prototype // true fproxy.foo === "Hello, foo" // true 调用get
三Proxy 支持的拦截操作一览
---get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。
---set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
---has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
---deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
---ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
---getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
---defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
---preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
---getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
---isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
---setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
---apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
---construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
四 this 问题
主要原因就是在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理。
const target4 = { m: function () { debugger console.log(this === proxy4); } }; const handler4 = {}; let proxy4 = new Proxy(target4, handler4); target4.m() // false proxy4.m() // true
标签:target,Object,propKey,Proxy,拦截,proxy 来源: https://www.cnblogs.com/dwzheng/p/10473853.html