Jansiel Notes

ES6之Proxy

Proxy属性操作介绍

  • 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循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而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)。

常用的Proxy属性

下面是关于 Proxy 的一些详解

创建一个 Proxy

使用 Proxy 构造函数来创建一个代理对象。Proxy 接受两个参数:目标对象和一个处理器对象(handler)。

 1const target = { name: \'John\', age: 25 };
 2
 3const handler = {
 4  get: function (target, prop) {
 5    console.log(`Getting property ${prop}`);
 6    return target[prop];
 7  },
 8  set: function (target, prop, value) {
 9    console.log(`Setting property ${prop} to ${value}`);
10    target[prop] = value;
11  }
12};
13
14const proxy = new Proxy(target, handler);

拦截操作

handler 对象中的各种方法可以用来拦截不同的操作。以下是一些常见的拦截方法:

  1. get(target, prop, receiver): 在读取属性时触发。
    1console.log(proxy.name); // 输出: Getting property name
    
  2. set(target, prop, value, receiver): 在设置属性时触发。
    1proxy.age = 30; // 输出: Setting property age to 30
    
  3. has(target, prop)·: 在使用 in` 运算符检查属性是否存在时触发。
    1console.log(\'name\' in proxy); // 输出: true
    
  4. deleteProperty(target, prop): 在使用 delete 运算符删除属性时触发。
    1delete proxy.age; // 输出: Deleting property age
    
  5. apply(target, thisArg, argumentsList): 在函数调用时触发。
     1const funcProxy = new Proxy(function (a, b) {
     2  return a + b;
     3}, {
     4  apply: function (target, thisArg, argumentsList) {
     5    console.log(\'Calling function with args:\', argumentsList);
     6    return target.apply(thisArg, argumentsList);
     7  }
     8});
     9
    10console.log(funcProxy(2, 3)); // 输出: Calling function with args: [2, 3], 返回: 5
    

其他拦截方法

Proxy 还提供了其他一些拦截方法,例如 construct(用于拦截 new 操作符)、getPrototypeOfsetPrototypeOfgetOwnPropertyDescriptor 等。你可以根据需要选择性地使用这些拦截方法。

注意事项

  1. 在使用 Proxy 时,要注意避免陷入无限循环。比如,在 get 拦截中,如果你返回了代理对象本身,可能会导致无限循环。
  2. Proxy 并不是万能的,它无法拦截一些内部操作,比如直接通过 Object.defineProperty 修改属性的属性描述符。
  3. Proxy 是一个强大且灵活的特性,可以用于实现许多高级的对象操作和元编程功能。

兼容性

Jansiel_Essay_1700239060876