JavaScript Proxy--vue3使用的响应式对象

91 阅读1分钟

定义

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

语法

const p = new Proxy(target,handler)

参数

target: 要使用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组、函数、甚至另一个代理) handler: 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理P的行为

方法

handler.get()

handler.get()  方法用于拦截对象的读取属性操作

var p = new Proxy(target, {
  get: function (target, property, receiver) {},
});
  • target

  • 目标对象。

  • property

  • 被获取的属性名。

  • receiver

  • Proxy 或者继承 Proxy 的对象

const target = {
  age: "18",
  name: "小明",
};

const handler = {
  get: function (target, prop, receiver) {
    if (target.age === "18") {
      return "年龄";
    }
  },
};

const proxy = new Proxy(target, handler);

console.log(proxy.age); // "年龄"

handler.set()

handler.set()  方法是设置属性值操作的捕获器

const perple = { age: 4 };

const handler = {
  set(obj, prop, value) {
    if (prop === 'age' && value % 2 !== 0) {
      console.log('单数');
    } else {
      return Reflect.set(...arguments);
    }
  },
};

const proxy = new Proxy(perple, handler);

proxy.age = 1;
// "单数"

console.log(proxy.age);
// 4

proxy.age = 2;
console.log(proxy.age);
// 2

更多方法API详见MDN:developer.mozilla.org/zh-CN/docs/…

关于Object.defineProperty与proxy的区别

  1. proxy可以代理整个对象,defineproperty只代理对象上的某个属性
  2. proxy对代理对象的监听更加丰富
  3. proxy代理会生成新的对象,不会修改被代理对象本身
  4. proxy不兼容IE浏览器
  5. difineproperty对于数组的一些方法监听不到
  6. proxy性能更好一些,proxy与defineproperty都不能监听到对象深层次的变化,都需要递归去处理的,vue3处理的方式是在get中进行递归响应的,性能更好。