0

0

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

聖光之護

聖光之護

发布时间:2025-10-03 11:09:11

|

549人浏览过

|

来源于php中文网

原创

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

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

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

Proxy的基本原理

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

实现数组变动监听

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

NatAgent
NatAgent

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

420

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

536

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

311

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

77

2025.09.10

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

779

2023.08.22

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

319

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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