当前位置: 首页 > 工具软件 > jsproxy > 使用案例 >

js之proxy

皇甫宇定
2023-12-01

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

语法

// target: 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
// handler: 一个对象,该对象的属性值通常是函数,定义了代理各种操作时p的行为。对象上的属性名是特定且可选的,如果没有某个属性,就会保留源对象的默认行为。
const p = new Proxy(target, handler)

handler 对象的方法有:

这些方法和Reflect的方法有明显的对应关系:

// 拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
handler.apply(target, thisArg, args)	
// 拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
handler.construct(target, args)
// 拦截对象属性的读取,比如proxy.foo和proxy['foo']。
handler.get(target, name, receiver)
// 拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
handler.set(target, name, value, receiver)
// 拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
handler.defineProperty(target, name, desc)
// 拦截delete proxy[propKey]的操作,返回一个布尔值。
handler.deleteProperty(target, name)
// 拦截propKey in proxy的操作,返回一个布尔值。
handler.has(target, name)
// 拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
handler.ownKeys(target)
// 拦截Object.isExtensible(proxy),返回一个布尔值。
handler.isExtensible(target)
// 拦截Object.preventExtensions(proxy),返回一个布尔值。
handler.preventExtensions(target)
// 拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
handler.getOwnPropertyDescriptor(target, name)
// 拦截Object.getPrototypeOf(proxy),返回一个对象。
handler.getPrototypeOf(target)
// 拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
Reflect.setPrototypeOf(target, prototype)

使用场景举例

1.数据只读

let data = new Proxy(response.data, {
  set(obj, key, value) {
    return false
  }
})
class Component {
  constructor () {
    this.proxy = new Proxy({
      id: Math.random().toString(36).slice(-8)
    })
  }
  get id () {
    return this.proxy.id
  }
}

2.数据校验

// Validator.js
export default (obj, key, value) => {
  if (Reflect.has(key) && value > 20) {
    obj[key] = value
  }
}

import Validator from './Validator'
let data = new Proxy(response.data, {
  set: Validator
})

创建可取消的代理

Proxy.revocable()方法返回一个可取消的 Proxy 实例。
Proxy.revocable()方法返回一个对象,该对象的proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例。
当执行revoke函数之后,再访问Proxy实例,就会抛出一个错误。
Proxy.revocable()的一个使用场景是,目标对象不允许直接访问,必须通过代理访问,一旦访问结束,就收回代理权,不允许再次访问。

let target = {};
let handler = {};

let {proxy, revoke} = Proxy.revocable(target, handler);

proxy.foo = 123;
proxy.foo // 123

revoke();
proxy.foo // TypeError: Revoked
 类似资料: