跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
JavaScript不可变性
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= JavaScript不可变性 = '''不可变性'''(Immutability)是函数式编程中的核心概念,指数据一旦创建就不能被修改。在JavaScript中,虽然变量默认是可变的,但通过特定的技术可以实现不可变性,从而提高代码的可预测性、简化状态管理并减少副作用。 == 基本概念 == 不可变性意味着: * 数据创建后不能被更改。 * 任何“修改”操作都会返回一个新的数据副本,而非直接修改原数据。 * 有助于避免意外的副作用,使程序更易于调试和测试。 === 可变 vs 不可变 === 在JavaScript中,原始类型(如字符串、数字、布尔值)默认是不可变的,而对象和数组是可变的。 <syntaxhighlight lang="javascript"> // 原始类型不可变 let str = "hello"; str[0] = "H"; // 无效,str仍然是"hello" // 对象可变 let obj = { a: 1 }; obj.a = 2; // obj被修改为 { a: 2 } </syntaxhighlight> == 实现不可变性的方法 == === 使用 const 声明 === `const` 可以防止变量重新赋值,但不会阻止对象内部的修改: <syntaxhighlight lang="javascript"> const arr = [1, 2, 3]; arr.push(4); // 仍然可以修改数组 </syntaxhighlight> === 使用 Object.freeze === `Object.freeze` 可以浅冻结对象,使其属性不可修改: <syntaxhighlight lang="javascript"> const obj = Object.freeze({ a: 1 }); obj.a = 2; // 静默失败(严格模式下会报错) </syntaxhighlight> === 使用不可变库 === 如 [https://immutable-js.com/ Immutable.js] 或 [https://immerjs.github.io/immer/ Immer] 提供深层次的不可变性支持。 == 不可变操作示例 == === 数组操作 === 使用 `concat`、`slice`、`map`、`filter` 等返回新数组的方法: <syntaxhighlight lang="javascript"> const original = [1, 2, 3]; const updated = original.concat(4); // [1, 2, 3, 4] </syntaxhighlight> === 对象操作 === 使用展开运算符或 `Object.assign` 创建新对象: <syntaxhighlight lang="javascript"> const original = { a: 1, b: 2 }; const updated = { ...original, b: 3 }; // { a: 1, b: 3 } </syntaxhighlight> == 性能考虑 == 不可变性可能导致内存开销,因为每次修改都会创建新对象。但现代JavaScript引擎(如V8)通过结构共享(Structural Sharing)优化性能。 <mermaid> graph LR A[原数据] --> B[修改操作] B --> C[新数据] A -.共享未修改部分.-> C </mermaid> == 实际应用案例 == === React 状态管理 === React 推崇不可变性,状态更新必须通过 `setState` 或 `useState` 返回新对象: <syntaxhighlight lang="javascript"> function Counter() { const [state, setState] = useState({ count: 0 }); // 正确做法:返回新对象 const increment = () => setState(prev => ({ ...prev, count: prev.count + 1 })); } </syntaxhighlight> === Redux Reducer === Redux 要求 reducer 必须是纯函数,返回新状态: <syntaxhighlight lang="javascript"> function reducer(state = initialState, action) { switch (action.type) { case 'ADD_ITEM': return { ...state, items: [...state.items, action.payload] }; default: return state; } } </syntaxhighlight> == 数学基础 == 不可变数据可以被视为数学中的值:<math>f(x)</math> 总是返回相同结果,不会改变 <math>x</math> 本身。 == 总结 == {| class="wikitable" |- ! 方法 !! 优点 !! 缺点 |- | `const` || 防止重新赋值 || 不阻止对象修改 |- | `Object.freeze` || 浅层不可变 || 不适用于嵌套对象 |- | 不可变库 || 深层不可变 || 需要学习额外API |} 不可变性是构建可靠JavaScript应用的重要模式,尤其在函数式编程和现代前端框架中广泛应用。初学者应从简单的 `const` 和展开运算符开始,逐步掌握更高级的不可变技术。 [[Category:编程语言]] [[Category:JavaScript]] [[Category:Javascript函数式编程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)