ES6从入门到精通:Proxy与Reflect

Proxy 的基本概念

Proxy 用于创建对象的代理,拦截并自定义对象的基本操作(如属性读取、赋值、函数调用等)。通过 new Proxy(target, handler) 创建,target 为目标对象,handler 为拦截操作的对象。

const target = { name: 'Alice' };
const handler = {
  get(target, prop) {
    return prop in target ? target[prop] : 'default';
  }
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 'Alice'
console.log(proxy.age);  // 'default'

Proxy 的常见拦截操作

  • get(target, prop, receiver):拦截属性读取。
  • set(target, prop, value, receiver):拦截属性赋值。
  • has(target, prop):拦截 in 操作符。
  • deleteProperty(target, prop):拦截 delete 操作。
  • apply(target, thisArg, args):拦截函数调用。
const handler = {
  set(target, prop, value) {
    if (prop === 'age' && typeof value !== 'number') {
      throw new TypeError('Age must be a number');
    }
    target[prop] = value;
    return true; // 表示成功
  }
};

Reflect 的基本用法

Reflect 提供与 Proxy 拦截操作一一对应的静态方法,用于简化操作。例如:

  • Reflect.get(target, prop) 替代 target[prop]
  • Reflect.set(target, prop, value) 替代 target[prop] = value
const obj = { a: 1 };
Reflect.set(obj, 'b', 2);
console.log(Reflect.get(obj, 'b')); // 2

Proxy 与 Reflect 结合使用

通过 Reflect 实现默认行为,避免手动操作目标对象。

const handler = {
  get(target, prop) {
    console.log(`Accessing ${prop}`);
    return Reflect.get(target, prop);
  }
};
const proxy = new Proxy({ a: 1 }, handler);
console.log(proxy.a); // 输出日志后返回 1

实际应用场景

  • 数据校验:通过 set 拦截实现动态类型检查。
  • 日志记录:拦截操作并记录访问日志。
  • 惰性初始化:代理对象按需加载资源。
const validator = {
  set(target, prop, value) {
    if (prop === 'email' && !value.includes('@')) {
      throw new Error('Invalid email');
    }
    return Reflect.set(target, prop, value);
  }
};

注意事项

  • Proxy 的 this 问题:代理后方法内的 this 可能指向代理对象而非目标对象。
  • 性能影响:频繁拦截可能降低性能,需谨慎使用。
const target = {
  checkThis() { return this === proxy; }
};
const proxy = new Proxy(target, {});
console.log(target.checkThis()); // false
console.log(proxy.checkThis());  // true

你可能感兴趣的:(ES6从入门到精通,es6,javascript,前端)