JavaScript中不可变数据指创建后无法修改,需通过生成新数据表达变化;它避免意外修改、提升调试与组件隔离能力,优化状态管理性能,并天然支持函数式编程与并发安全。

JavaScript中的不可变数据,是指一旦创建就无法被修改的数据。它不禁止你“改变状态”,而是要求你通过生成新数据来表达变化,而不是直接修改原对象或数组。
避免意外修改和副作用
可变数据容易在多处被无意修改。比如一个用户对象被多个函数引用,其中一个函数调用了 user.name = "Bob",其他地方读取时可能突然发现名字变了,却找不到源头。不可变性强制每次更新都返回新对象,原始数据始终如一,从根源上切断这类隐性依赖。
- 传参更安全:函数拿到数据后无法偷偷改掉原始值
- 调试更容易:出问题时能快速定位是哪次“新建”引入了异常数据
- 组件间隔离更强:React中父组件传给子组件的props不会被子组件意外污染
提升状态管理与性能判断效率
当状态必须用新对象表示时,引用变化就成了天然的“是否更新”信号。React、Redux 等框架依赖浅比较(===)快速判断是否需要重渲染或触发 reducer。如果数据可变,哪怕内容变了,引用没变,就会跳过更新;而不可变更新确保“变了就换引用”,让判断既简单又可靠。
- 不用深比较,节省大量计算开销
- 配合 useMemo、React.memo 更容易命中缓存
- 时间旅行调试、撤销/重做功能实现成本大幅降低
天然支持函数式编程与并发安全
纯函数要求输入相同则输出相同,且不产生副作用——这和不可变数据是绝配。两者结合,代码逻辑更线性、更易测试、更易组合。另外,在异步或并行场景下(比如 Web Worker 处理数据),不可变数据无需加锁,多个任务可以同时读取同一份数据,彻底规避竞态条件。
技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作
立即学习“Java免费学习笔记(深入)”;
- map/filter/reduce 等操作天然契合不可变习惯
- 异步回调中不再担心“上一个 await 改了我刚读的数据”
- 服务端渲染(SSR)或同构应用中状态更可控
实际怎么做到不可变
不需要立刻上库。ES6 提供了足够多轻量手段:
- 对象更新用 {...obj, key: newValue}
- 数组添加用 [...arr, newItem],删除用 arr.filter(),替换用 arr.map()
- 深层嵌套可用结构化解构 + 展开,或借助 Immer 写起来像可变但底层自动转不可变
- 复杂场景再考虑 Immutable.js 或 Zustand + immer 插件等成熟方案









