Proxy拦截器

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

  • 语法
  • target
    要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
  • handler
    一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
    const p = new Proxy(target, handler)
    // target: 所要拦截的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
    // handler:一个对象,定义要拦截的行为
    
  • Proxy.revocable()
    创建一个可撤销的Proxy对象。
    

捕捉器

  • handler.getPrototypeOf()
    Object.getPrototypeOf 方法的捕捉器。
    Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)
    
    handler.setPrototypeOf()
    Object.setPrototypeOf 方法的捕捉器。
    
    handler.isExtensible()
    Object.isExtensible 方法的捕捉器。
    
    handler.preventExtensions()
    Object.preventExtensions 方法的捕捉器。
    
    handler.getOwnPropertyDescriptor()
    Object.getOwnPropertyDescriptor 方法的捕捉器。
    
    handler.defineProperty()
    Object.defineProperty 方法的捕捉器。
    
    handler.has()
    in 操作符的捕捉器。
    
    handler.get()
    属性读取操作的捕捉器。
    
    handler.set()
    属性设置操作的捕捉器。
    
    handler.deleteProperty()
    delete 操作符的捕捉器。
    
    handler.ownKeys()
    Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
    
    handler.apply()
    函数调用操作的捕捉器。
    
    handler.construct()
    new 操作符的捕捉器。
    
  • 示例
    const handler = {
        get: function(obj, prop) {
        //obj是实例对象 prop是现在访问的属性名
        // 这里可以对应该返回的prop进行修改
            return prop in obj ? obj[prop] : 37;
        }
    };
    
    const p = new Proxy({}, handler);
    p.a = 1;
    p.b = undefined;
    
    console.log(p.a, p.b);      // 1, undefined
    console.log('c' in p, p.c); // false, 37
    
### 关于 Proxy 的 13 种拦截器 JavaScript 中的 `Proxy` 提供了多种拦截操作的方法,这些方法被称为 **拦截器** 或者 **陷阱 (traps)**。以下是完整的 13 种拦截器及其功能描述: #### 1. `get(target, propKey, receiver)` 用于拦截对象属性的读取操作。 ```javascript const handler = { get(target, propKey, receiver) { console.log(`Getting ${propKey}`); return Reflect.get(target, propKey, receiver); } }; let target = { name: 'Alice' }; let proxy = new Proxy(target, handler); console.log(proxy.name); // 输出 "Getting name", 然后返回 Alice ``` [^1] --- #### 2. `set(target, propKey, value, receiver)` 用于拦截对象属性的设置操作。 ```javascript const handler = { set(target, propKey, value, receiver) { console.log(`Setting ${propKey} to`, value); return Reflect.set(target, propKey, value, receiver); } }; let target = {}; let proxy = new Proxy(target, handler); proxy.name = 'Bob'; // 设置并打印日志 console.log(proxy.name); // Bob ``` --- #### 3. `has(target, propKey)` 用于拦截 `in` 操作符。 ```javascript const handler = { has(target, propKey) { if (propKey === 'secret') { return false; } return Reflect.has(target, propKey); } }; let target = { secret: true }; let proxy = new Proxy(target, handler); console.log('secret' in proxy); // false console.log('name' in proxy); // 如果有其他键,则正常返回 ``` [^2] --- #### 4. `deleteProperty(target, propKey)` 用于拦截 `delete obj[propKey]` 操作。 ```javascript const handler = { deleteProperty(target, propKey) { console.log(`Deleting property ${propKey}`); return Reflect.deleteProperty(target, propKey); } }; let target = { a: 1 }; let proxy = new Proxy(target, handler); delete proxy.a; // 删除并记录日志 console.log('a' in proxy); // false ``` --- #### 5. `ownKeys(target)` 用于拦截 `Object.getOwnPropertyNames(obj)` 和 `JSON.stringify()` 等获取目标对象自身属性的操作。 ```javascript const handler = { ownKeys(target) { return ['foo', 'bar']; } }; let target = {}; let proxy = new Proxy(target, handler); console.log(Object.keys(proxy)); // ["foo", "bar"] ``` --- #### 6. `apply(target, thisArg, argumentsList)` 用于拦截函数调用操作。 ```javascript function sum(a, b) { return a + b; } const handler = { apply(target, thisArg, args) { console.log(args); return Reflect.apply(...arguments); } }; let proxy = new Proxy(sum, handler); console.log(proxy(1, 2)); // 打印参数 [1, 2], 返回 3 ``` --- #### 7. `construct(target, argArray, newTarget)` 用于拦截通过 `new` 调用构造函数的行为。 ```javascript class MyClass {} const handler = { construct(target, args, newTarget) { console.log('Creating instance with:', args); return Reflect.construct(target, args, newTarget); } }; let proxy = new Proxy(MyClass, handler); new proxy(); // 创建实例时触发日志 ``` --- #### 8. `defineProperty(target, propKey, attributes)` 用于拦截 `Object.defineProperty(obj, key, desc)` 操作。 ```javascript const handler = { defineProperty(target, propKey, attributes) { console.log(`Defining property ${propKey}`, attributes); return Reflect.defineProperty(target, propKey, attributes); } }; let target = {}; let proxy = new Proxy(target, handler); Object.defineProperty(proxy, 'test', { configurable: true }); // 定义 test 属性并打印日志 ``` --- #### 9. `getOwnPropertyDescriptor(target, propKey)` 用于拦截 `Object.getOwnPropertyDescriptor(obj, propKey)` 操作。 ```javascript const handler = { getOwnPropertyDescriptor(target, propKey) { const descriptor = Reflect.getOwnPropertyDescriptor(target, propKey); if (descriptor !== undefined && typeof descriptor.value === 'number') { descriptor.value *= 2; } return descriptor; } }; let target = { num: 10 }; let proxy = new Proxy(target, handler); console.log(Object.getOwnPropertyDescriptor(proxy, 'num')); // {value: 20, ...} ``` --- #### 10. `isExtensible(target)` 用于拦截 `Object.isExtensible(obj)` 操作。 ```javascript const handler = { isExtensible(target) { console.log('Checking extensibility'); return Reflect.isExtensible(target); } }; let target = {}; let proxy = new Proxy(target, handler); console.log(Object.isExtensible(proxy)); // true 并打印日志 ``` --- #### 11. `preventExtensions(target)` 用于拦截 `Object.preventExtensions(obj)` 操作。 ```javascript const handler = { preventExtensions(target) { console.log('Preventing extensions'); return Reflect.preventExtensions(target); } }; let target = {}; let proxy = new Proxy(target, handler); Object.preventExtensions(proxy); // 阻止扩展并打印日志 ``` --- #### 12. `getPrototypeOf(target)` 用于拦截 `Object.getPrototypeOf(obj)` 操作。 ```javascript const handler = { getPrototypeOf(target) { console.log('Fetching prototype...'); return Reflect.getPrototypeOf(target); } }; let target = Object.create({ foo: 'bar' }); let proxy = new Proxy(target, handler); console.log(Object.getPrototypeOf(proxy)); // 获取原型链上的对象 ``` --- #### 13. `setPrototypeOf(target, proto)` 用于拦截 `Object.setPrototypeOf(obj, proto)` 操作。 ```javascript const handler = { setPrototypeOf(target, proto) { console.log('Changing prototype...'); return Reflect.setPrototypeOf(target, proto); } }; let target = {}; let proxy = new Proxy(target, handler); Object.setPrototypeOf(proxy, null); // 更改原型并打印日志 ``` --- ### 总结 以上列举了 JavaScript 中 `Proxy` 支持的所有 13 种拦截器,并提供了每种拦截器的具体实现方式和实际应用案例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值