Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改。
Proxy 可以理解在目标对象架设一个“拦截”层外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和修改。
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.get(target, key, value, receiver) } }) obj.count = 1 // 触发 set 事件 setting count ++obj.count // 触发 get 和 set 事件 getting count setting count
Proxy 重载了点运算符,用自己的定义覆盖了语言的原始定义。
/** * new Proxy() 生成一个 Proxy 实例 * target 参数表示所要拦截的目标对象 * handler 参数也是一个对象,用来定制拦截行为 */ let proxy = new Proxy(target, handler)
注意:
要使 Proxy 起作用,必须针对 Proxy 实例进行操作,而不是目标对象。
例子:
let target = {} let handler = {} var proxy = new Proxy(target, handler) proxy.count = 1 console.log(proxy.count) // 1 target.count = 2 console.log(target.count) // 2
现在有一个技巧:将 Proxy 设置到 object.proxy 属性中,从而可以在 object 对象上调用。
let object = { proxy: new Proxy(target, handler) }
也可以将 proxy 直接挂载到原型上
let proxy = new Proxy({}, { get: function(target, handler) { return ‘houfee‘ } }) let obj = Object.create(proxy) console.log(obj.name) // houfee // proxy 是 obj 原型上的对象,根据原型链会在 proxy 对象读取该属性,导致被拦截
同一个拦截器函数设置多个操作:
var handler = { get: function(target, name) { if(name === ‘prototype‘) { return Object.prototype } return `holle ${name}` }, apply: function(target, thisBinding, args) { return args[0] }, construct: function(target, args) { return {value: args[1]} } } var fproxy = new Proxy(function(x, y) { return x * y }, handler) console.log(fproxy(2, 5)) // 2 console.log(new fproxy(2, 5)) // {value: 5} console.log(fproxy.prototype === Object.prototype) // true console.log(fproxy.houfee) // holle houfee
1.get(target, propKey, receiver)
拦截对象属性的读取,比如 proxy.houfee 和 proxy[‘houfee‘],最后一个参数receiver是一个可选参数。
2.set(target, propKey, value, receiver)
拦截对象属性的设置,比如 proxy.houfee = v 和 proxy[‘houfee‘] = v ,返回一个boolean值
3.has(target, propKey)
拦截 propKey in proxy 的操作,返回一个布尔值。
4.deleteProperty(target, propKey)
拦截 delete proxy[propKey] 的操作,返回一个布尔值。
5.ownKeys(target)
拦截 Object.getOwnPropertyNames(proxy)、 Object.getOwnPropertySymbols(proxy)、Object(proty),返回一个数组。
该方法返回目标对象所有自身属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。
6.getOwnPropertyDescriptor(target, propKey)
拦截 Object.getOwnPropertyDescriptor(target, propKey),返回属性的描述对象。
7.defineProperty(target, propKey, propDesc)
拦截 Object.defineProperty(target, propKey, propDesc)、Object.defineProperties(proxy, propDesc),返回一个布尔值。
8.preventExtensions(target)
拦截 Object.preventExtensions(proxy),返回一个布尔值。
9.getPrototypeOf(target)
拦截 Object.getPrototypeOf(target),返回一个对象。
10.isExtensible(target)
拦截 Object.isExtensible(target),返回一个布尔值。
11.setPrototypeOf(target, proto)
拦截 Object.setPrototypeOf(target, proto),返回一个布尔值。如果目标对象是函数,呢么还有2种额外操作可以拦截。
12.apply(target, object, args)
拦截 Proxy 实例,并将其作为函数调用,比如 proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
13.construct(target, args)
拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(...args)。
原文:https://www.cnblogs.com/houfee/p/11300204.html