【JS 代理Proxy】

JavaScript 代理

JavaScript 代理是一种强大的功能,它允许你拦截对象上的操作,并在它们被执行之前或之后执行自定义代码。这使得开发人员能够创建功能强大的、动态的对象,以及更高级别的代码抽象。

JavaScript 代理的主要用途是创建可观察对象、虚拟对象和代理实现。它们允许你将逻辑封装在代理中,并在对象上执行操作时访问对象的属性和方法。代理还可以用于数据验证、缓存和数据重载等功能。

以下是代理的一些示例用法:

  1. 可观察对象:可以使用代理来创建可观察对象。当观察者对此对象进行访问时,代理被激活,从而触发通知。

  2. 虚拟对象:代理可以用于创建虚拟对象。虚拟对象是一种懒加载机制,只有在需要时才会加载对象。

  3. 代理实现:代理可以用于创建代理实现。使用代理来封装对象的访问,可以在不破坏类型安全的情况下修改对象的行为。

JavaScript 代理是一项强大的功能,可以用于创建高级别的对象抽象和引入更高级别的设计模式。它们是一种常见的工具,可以为 JavaScript 应用程序带来许多好处。

JS 代理(Proxy)是 ES6 中新增的特性,它可以拦截对对象的访问和操作,从而可以在对象的基础上增加自定义的行为。

JS 代理的语法

JS 代理的语法如下:

let proxy = new Proxy(target, handler);

其中,target 是要拦截的对象,handler 是一个包含拦截器(即处理程序)的对象。拦截器可以拦截对象的各种操作,例如访问属性、设置属性、调用方法等。

下面是 JS 代理的一些应用示例:

  1. 访问属性

可以使用代理拦截对对象属性的读取,例如可以在属性读取时输出日志。

let obj = { name: 'Jack', age: 20 };
let proxy = new Proxy(obj, {
  get(target, prop) {
    console.log(`读取了属性 ${prop}`);
    return target[prop];
  }
});

console.log(proxy.name); // 输出 "读取了属性 name" 和 "Jack"
console.log(proxy.age); // 输出 "读取了属性 age" 和 20
  1. 设置属性

可以使用代理拦截对对象属性的设置,例如可以在属性设置时进行验证或记录日志。

let obj = { name: 'Jack', age: 20 };
let proxy = new Proxy(obj, {
  set(target, prop, value) {
    if (prop === 'age') {
      if (value < 0 || value > 120) {
        throw new Error('年龄必须在 0 到 120 之间');
      }
    }
    console.log(`设置属性 ${prop}${value}`);
    target[prop] = value;
  }
});

proxy.name = 'Tom'; // 输出 "设置属性 name 为 Tom"
proxy.age = 130; // 抛出错误 "年龄必须在 0 到 120 之间"
  1. 调用方法

可以使用代理拦截对对象方法的调用,例如可以在方法调用前后输出日志。

let obj = {
  getName() {
    console.log('调用了 getName 方法');
    return 'Jack';
  },
  getAge() {
    console.log('调用了 getAge 方法');
    return 20;
  }
};

let proxy = new Proxy(obj, {
  apply(target, thisArg, args) {
    console.log(`调用了方法 ${args[0]}`);
    return target[args[0]]();
  }
});

console.log(proxy.getName()); // 输出 "调用了方法 getName"、"调用了 getName 方法" 和 "Jack"
console.log(proxy.getAge()); // 输出 "调用了方法 getAge"、"调用了 getAge 方法" 和 20
  1. 拦截器代理

可以使用代理拦截器代理对象,从而可以对被代理对象的所有操作进行拦截。

let obj = {
  name: 'Jack',
  age: 20,
  getName() {
    return this.name;
  },
  getAge() {
    return this.age;
  }
};

let handler = {
  get(target, prop) {
    console.log(`读取了属性 ${prop}`);
    return target[prop];
  },
  set(target, prop, value) {
    console.log(`设置属性 ${prop}${value}`);
    target[prop] = value;
  },
  apply(target, thisArg, args) {
    console.log(`调用了方法 ${args[0]}`);
    return target[args[0]]();
  }
};

let proxy = new Proxy(obj, handler);

console.log(proxy.name); // 输出 "读取了属性 name" 和 "Jack"
proxy.name = 'Tom'; // 输出 "设置属性 name 为 Tom"
console.log(proxy.getName()); // 输出 "调用了方法 getName"、"读取了属性 name" 和 "Tom"

代理拦截器方法集合

JS 代理对象的拦截器方法集合由以下方法组成:

  1. get(target, property, receiver):用于拦截对象属性的读取操作,接收三个参数,分别为目标对象、属性名和代理对象本身,返回值为读取的属性值。

  2. set(target, property, value, receiver):用于拦截对象属性的赋值操作,接收四个参数,分别为目标对象、属性名、属性值和代理对象本身,返回值为布尔值,表示属性是否赋值成功。

  3. has(target, property):用于拦截 in 操作符,即判断属性是否存在于对象中,接收两个参数,分别为目标对象和属性名,返回值为布尔值,表示属性是否存在于对象中。

  4. deleteProperty(target, property):用于拦截 delete 操作符,即删除对象属性,接收两个参数,分别为目标对象和属性名,返回值为布尔值,表示属性是否删除成功。

  5. apply(target, thisArg, args):用于拦截函数的调用操作,接收三个参数,分别为目标函数、目标函数的 this 值和函数的参数列表,返回值为函数调用的结果。

  6. construct(target, args, newTarget):用于拦截构造函数的调用操作,接收三个参数,分别为目标构造函数、构造函数的参数列表和代理对象本身,返回值为新创建的对象。

  7. getOwnPropertyDescriptor(target, property):用于拦截 Object.getOwnPropertyDescriptor(),即获取属性的描述对象,接收两个参数,分别为目标对象和属性名,返回值为属性的描述对象。

  8. defineProperty(target, property, descriptor):用于拦截 Object.defineProperty() 和 Object.defineProperties(),即定义对象属性,接收三个参数,分别为目标对象、属性名和属性的描述对象,返回值为布尔值,表示属性是否定义成功。

  9. getPrototypeOf(target):用于拦截 Object.getPrototypeOf(),即获取对象的原型对象,接收一个参数,即目标对象,返回值为对象的原型对象。

  10. setPrototypeOf(target, prototype):用于拦截 Object.setPrototypeOf(),即设置对象的原型对象,接收两个参数,分别为目标对象和原型对象,返回值为布尔值,表示原型对象是否设置成功。

  11. isExtensible(target):用于拦截 Object.isExtensible(),即判断对象是否可扩展,接收一个参数,即目标对象,返回值为布尔值,表示对象是否可扩展。

  12. preventExtensions(target):用于拦截 Object.preventExtensions(),即防止对象扩展,接收一个参数,即目标对象,返回值为布尔值,表示是否防止对象扩展成功。

  13. getOwnPropertyNames(target):用于拦截 Object.getOwnPropertyNames(),即获取对象的属性名数组,接收一个参数,即目标对象,返回值为属性名数组。

  14. ownKeys(target):用于拦截 Object.getOwnPropertySymbols()、Object.getOwnPropertyNames() 和 Object.keys(),即获取对象的全部属性名数组,接收一个参数,即目标对象,返回值为属性名数组。

  15. apply(target, thisArg, args):用于拦截函数的调用操作,接收三个参数,分别为目标函数、目标函数的 this 值和函数的参数列表,返回值为函数调用的结果。

这些拦截器方法可以被用于代理对象的各种操作,以实现对目标对象的更细粒度的控制。
在 JS 代理中,拦截器参数是指在代理的过程中,可以使用的一些参数对象。这些参数对象分为两类:拦截器方法参数和附加参数。

你可能感兴趣的:(JS,再刷JS,javascript,开发语言,ecmascript)