当前位置: 首页 > 工具软件 > Object-proxy > 使用案例 >

JS 基础--- proxy(代理)

卫阳曜
2023-12-01

JS Proxy

1.概述

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

2.语法

let p = new Proxy(target, handler);

3.参数

target :需要使用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler: 一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。具体的handler相关函数请查阅官网
下面是使用示例,一个简单的代理:

  let test = {
    name: "小红"
  };
  test = new Proxy(test, {
    get(target, key) {
      console.log('获取了getter属性');
      return target[key];
    }
  });
  console.log(test.name);

上方的案例,我们首先创建了一个test对象,里面有name属性,然后我们使用Proxy将其包装起来,再返回给test,此时的test已经成为了一个Proxy实例,我们对其的操作,都会被Proxy拦截。
Proxy有两个参数,第一个是target,也就是我们传入的*test对象,另一个则是handler,也就是我们传入的第二个参数,一个匿名对象。在handler中定义了一个名叫get的函数,当我们获取 test的属性时,则会触发此函数。
咱们再来试试使用set来拦截一些操作,并将get返回值更改

  let xiaohong = {
    name: "小红",
    age: 15
  };
  xiaohong = new Proxy(xiaohong, {
    get(target, key) {
      let result = target[key];
      //如果是获取 年龄 属性,则添加 岁字
      if (key === "age") result += "岁";
      return result;
    },
    set(target, key, value) {
      if (key === "age" && typeof value !== "number") {
        throw Error("age字段必须为Number类型");
      }
      return Reflect.set(target, key, value);
      // 这句可以替换成
      // target[key] = value;
    }
  });
  console.log(`我叫${xiaohong.name}  我今年${xiaohong.age}了`);
  xiaohong.age = 12;

具体的参考 官方链接

4.Proxy与Object.defineProperty的优劣势对比

Proxy的优势:
可以直接监听对象而非属性
可以直接监听数组的变化
拦截方式较多
Proxy返回一个新对象,可以只操作新对象达到目的,而Object.defineProperty只能遍历对象属性直接修改
Proxy作为新标准将受到浏览器厂商重点持续的性能优化

Object.defineProperty的优势如下:
兼容性好,支持IE9

 类似资料: