js的proxy拦截

126 阅读2分钟

JavaScript 中的 Proxy 是一个内置的对象,用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。Proxy 用于拦截并定义对某个对象的操作,它允许你为这些操作定义自定义的行为。简单来说,Proxy 允许你创建一个对象的“代理”,这个代理可以对外部对该对象的操作进行拦截和处理。

Proxy 对象的语法如下:

const p = new Proxy(target, handler);
  • target:要包装的目标对象(可以是任何类型的对象,包括原生数组、函数、甚至另一个代理)。
  • handler:一个对象,其属性是当执行一个操作时定义行为的一组函数。

**handler** 对象可以包含以下捕获器(traps):

  • get(target, propKey, receiver):拦截对象属性的读取操作。
  • set(target, propKey, value, receiver):拦截对象属性的设置操作。
  • 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 循环等操作。
  • 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, thisArg, argumentsList):拦截函数调用的操作。
  • construct(target, argumentsList, newTarget):拦截 new 操作符的操作。

下面是一个简单的例子,展示了如何使用 Proxy 来拦截和自定义属性的读取和设置操作:

const handler = { 
  get: function(target, name) { 
    return name in target ? target[name] : '默认值'; 
  }, 
  set: function(target, name, value) { 
    if (name === 'age' && typeof value !== 'number') { 
      throw new TypeError('年龄必须是数字'); 
    } 
    target[name] = value; 
    return true; 
  } 
}; 
const person = new Proxy({}, handler); 
person.name = '张三'; // 设置属性 
console.log(person.name); // 读取属性,输出:"张三" 
console.log(person.age); // 读取未定义的属性,输出:"默认值" person.age = 30; // 设置属性 console.log(person.age); // 输出:30 person.age = '三十'; // 尝试设置非法值,将抛出错误

在这个例子中,Proxy 对象 person 的 get 捕获器用于定义当尝试访问一个不存在的属性时的返回值,而 set 捕获器用于确保 age 属性的值是一个数字。如果尝试给 age 赋予一个非数字值,set 捕获器将抛出一个错误。