当前位置:   article > 正文

Object.defineProperty和Proxy

object.defineproperty和proxy

区别

Object.defineProperty和Proxy都可以用于实现对象的响应式,但它们有一些区别:

  1. 语法和使用方式:
  • Object.defineProperty需要对对象的每个属性进行单独定义,并且需要指定get和set函数来实现属性的拦截。
  • Proxy可以直接对整个对象进行代理,并通过拦截器(handler)定义对对象的各种操作,包括get、set、delete、has等。
  1. 监听粒度:
  • Object.defineProperty只能监听对象的属性,无法监听整个对象或数组的变化。
  • Proxy可以监听对象的整个变化,包括属性的增加、删除和修改,以及数组的变化(push、pop、shift、unshift等)。
  1. 兼容性:
  • Object.defineProperty支持IE9及以上的现代浏览器。
  • Proxy不支持IE浏览器(除了Edge),只能在较新的现代浏览器中使用。但可以通过使用polyfill来实现对不支持Proxy的浏览器进行兼容。
  1. 性能:
  • Object.defineProperty的性能相对较差,因为每个属性都需要单独定义,而且无法监听整个对象或数组的变化。
  • Proxy的性能相对较好,因为它可以一次性对整个对象进行代理,并可以监听整个对象的变化。

综上所述,Proxy比Object.defineProperty更为强大和灵活,推荐在新项目中使用Proxy来实现对象的响应式。如果需要兼容老旧的浏览器,可以考虑使用Object.defineProperty,并配合一些辅助工具来实现类似的功能。

Object.defineProperty实现响应式

可以使用Object.defineProperty来实现一个简单的响应式系统,通过监听对象的所有属性并在属性值发生变化时触发回调函数

/**
 * 使用Object.defineProperty实现一个简单的响应式
 * @param data 监听的对象
 */
const defineReactiveByProperty = (data) => {
  for (let [key, value] of Object.entries(data)) {
    Object.defineProperty(data, key, {
      enumerable: true, // 可枚举
      configurable: true, // 可配置
      // 读取属性值时触发的函数
      get() {
        console.log(`读取属性${key}: ${value}`);
        return value;
      },
      // 设置属性值时触发的函数
      set(newValue) {
        console.log(`设置属性${key}为: ${newValue}`);
        value = newValue;
      },
    });
  }
  return data;
};

// 测试数据
const propertyData = defineReactiveByProperty({
  name: "Alice",
  age: 30,
});

propertyData.name; // 读取属性name: Alice
propertyData.age; // 读取属性age: 30

propertyData.name = "Bob"; // 设置属性name为: Bob
propertyData.age = 25; // 设置属性age为: 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

Proxy实现响应式

使用ES6的Proxy来实现一个简单的响应式系统,监听对象的所有属性并在属性值发生变化时触发回调函数。与前面的例子相比,Proxy提供了更为灵活和强大的响应式特性。

/**
 * 使用proxy实现一个简单的响应式
 * @param data 监听的对象
 * @param onChange 回调函数
 */
const defineReactiveByProxy = (data, onChange) => {
  return new Proxy(data, {
    // 拦截属性的读取
    get(target, key, receiver) {
      console.log(`读取属性${key}: ${target[key]}`);
      return target[key];
    },
    // 拦截属性的设置
    set(target, key, value, receiver) {
      console.log(`设置属性${key}为: ${value}`);
      target[key] = value;
      // 触发回调函数,通知属性值发生变化
      onChange && onChange(key, value);
      return true;
    },
  });
};
// 测试数据
const proxyData = defineReactiveByProxy(
  {
    name: "Alice",
    age: 30,
  },
  (key, value) => {
    console.log(`属性${key}的值已变为: ${value}`);
  }
);

proxyData.name; // 读取属性name: Alice
proxyData.age; // 读取属性age: 30

proxyData.name = "Bob"; // 设置属性name为: Bob
proxyData.age = 25; // 设置属性age为: 25

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/853781
推荐阅读
相关标签
  

闽ICP备14008679号