首页 > web前端 > js教程 > 正文

监听数组变动并触发额外任务:使用Proxy实现数据持久化

聖光之護
发布: 2025-10-03 11:09:11
原创
533人浏览过

监听数组变动并触发额外任务:使用proxy实现数据持久化

本文将详细介绍如何使用Proxy代理数组,监听数组变动并触发额外任务。

在JavaScript中,我们经常需要监听数组的变化,例如当数组通过push、splice等方法修改时,执行一些额外的操作。传统的set访问器只能捕获对整个数组的赋值操作,而无法感知数组内部的变动。为了解决这个问题,我们可以使用Proxy对象来代理数组,从而拦截对数组的各种操作。

Proxy的基本原理

Proxy对象允许你创建一个对象的代理,并拦截对该对象的基本操作,例如读取属性、写入属性、调用函数等。通过定义一个handler对象,我们可以指定在拦截到这些操作时应该执行的自定义行为。

实现数组变动监听

要监听数组的变动,我们需要拦截Proxy对象的set操作。set trap会在属性被赋值时触发,我们可以通过检查被赋值的属性是否为length来判断数组是否发生了变动。

腾讯智影-AI数字人
腾讯智影-AI数字人

基于AI数字人能力,实现7*24小时AI数字人直播带货,低成本实现直播业务快速增增,全天智能在线直播

腾讯智影-AI数字人 73
查看详情 腾讯智影-AI数字人

下面是一个示例代码,演示了如何使用Proxy来监听数组的变动,并在数组长度发生变化时将数组的内容持久化到sessionStorage中:

class Environment {
  constructor() {
    // 从sessionStorage中初始化数组,如果sessionStorage中没有数据,则初始化为空数组
    const crumbList =
      JSON.parse(sessionStorage.getItem('crumbs') ?? null) ?? [];

    this.crumbs = new Proxy(crumbList, {
      set(obj, prop, value) {
        // debugger;
        // console.log({ obj, prop, value });

        // 执行默认的set操作
        const result = Reflect.set(...arguments);

        // 如果被赋值的属性是length,则将数组的内容持久化到sessionStorage中
        if (prop === 'length') {
          // 将最新的数组内容保存到sessionStorage中
          sessionStorage.setItem('crumbs', JSON.stringify(crumbList));
        }
        return result;
      }
    });
    //  为 `this.crumbs` 代理添加一个自定义 `valueOf` 实现,该实现返回代理对象最新镜像状态的浅拷贝。
    Object.defineProperty(this.crumbs, 'valueOf', {
      value: function valueOf () {
        return [...crumbList];
      },
    });
  }
}

const env = new Environment();

const metricId = 6;
const concept = 'Back orders';

const crumb = { metricId, concept };

env.crumbs.push(crumb);

env.crumbs.push('foo');
env.crumbs.push('bar');

env.crumbs.length = 5;

env.crumbs.push('baz');
env.crumbs.push('biz');

env.crumbs.length = 9;

console.log('... after initial `push` operations and `crumbs.length` changes ...');
console.log({ "current value": env.crumbs });

env.crumbs.shift();
env.crumbs.pop();
env.crumbs.pop();

console.log('... after `shift` and `pop` operations ...');
console.log({ "current value": env.crumbs });

env.crumbs.splice(1, 3);

console.log('... after a final `splice` operation ...');
console.log({ "current valueOf()": env.crumbs.valueOf() });

console.log({ "currently stored JSON": sessionStorage.getItem('crumbs') });
登录后复制

代码解释

  1. Environment类: 创建了一个Environment类,该类使用 Proxy 包装了一个数组,以便能够拦截数组的修改。
  2. constructor: 构造函数从 sessionStorage 中检索 crumbs 数据,如果不存在则初始化一个空数组。然后,它创建一个新的 Proxy 实例来包装这个数组。
  3. Proxy: Proxy 接收两个参数:要代理的目标对象(crumbList 数组)和一个处理程序对象。
  4. set: 处理程序对象定义了一个 set 方法,该方法在代理对象的属性被设置时调用。该方法拦截对代理数组的属性设置操作。
  5. Reflect.set(...arguments): 这行代码使用 Reflect.set 执行原始的属性设置操作。Reflect 对象提供了一组用于操作对象的静态方法,Reflect.set 允许你以一种更安全和可控的方式设置属性。
  6. if (prop === 'length'): 此条件检查设置的属性是否为 length。当使用 push、pop、shift、unshift 或 splice 等修改数组的方法时,数组的 length 属性会发生变化。
  7. sessionStorage.setItem('crumbs', JSON.stringify(crumbList)): 如果 length 属性发生了变化,则此行代码将更新后的 crumbList 数组存储在 sessionStorage 中。JSON.stringify 用于将数组转换为 JSON 字符串,以便可以将其存储在 sessionStorage 中。
  8. Object.defineProperty: 为 this.crumbs 代理添加一个自定义 valueOf 实现,该实现返回代理对象最新镜像状态的浅拷贝。

注意事项

  • 使用Proxy会带来一定的性能开销,因此在性能敏感的场景下需要谨慎使用。
  • Proxy只能拦截对Proxy对象的操作,而不能拦截对原始对象的操作。
  • 需要注意兼容性问题,Proxy在一些旧版本的浏览器中可能不支持。

总结

通过使用Proxy对象,我们可以方便地监听数组的变动,并在数组发生变化时执行额外的任务。这种方法可以用于实现数据持久化、状态管理等功能,为我们的应用带来更多的灵活性和可扩展性。

以上就是监听数组变动并触发额外任务:使用Proxy实现数据持久化的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号