[Redux] Avoiding Array Mutations with concat(), slice(), and ...spread
For Redux, you cannot use mutable methods like push, splice. Need to use immutable methods such as concat, slice and ...spread
Html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> <script src="https://wzrd.in/standalone/expect@latest"></script> <script src="https://wzrd.in/standalone/deep-freeze@latest"></script> </head> <body> </body> </html>
push() vs concat()
push: modify the array;
concat: return a new array;
console.clear(); const addCounter = (list)=>{ list.push(0); return list; } const testAddCounter = ()=>{ const beforeList = []; const afterList = [0]; deepFreeze(beforeList); expect( addCounter(beforeList) ).toEqual(afterList); } testAddCounter(); console.log("All tests passing.."); /** "error" "TypeError: Can't add property 0, object is not extensible at addCounter (fegewebemu.js:5:8) at testAddCounter (fegewebemu.js:15:10) at fegewebemu.js:18:1" */ console.clear(); const addCounter = (list)=>{ let res = list.concat(0); return res; } const testAddCounter = ()=>{ const beforeList = []; const afterList = [0]; deepFreeze(beforeList); expect( addCounter(beforeList) ).toEqual(afterList); } testAddCounter(); console.log("All tests passing.."); // passing
Using ...spread:
console.clear(); const addCounter = (list)=>{ return [...list, 0]; } const testAddCounter = ()=>{ const beforeList = []; const afterList = [0]; deepFreeze(beforeList); expect( addCounter(beforeList) ).toEqual(afterList); } testAddCounter(); console.log("All tests passing.."); // Passing
splice() vs slice()
splice: modfiy array;
slices: return new array;
console.clear(); const removeCounter= (list, index)=>{ list.splice(index, 1); return list; } const testRemoveCounter = ()=>{ const beforeList = [0 ,10,20]; const afterList = [0, 20]; deepFreeze(beforeList); expect( removeCounter(beforeList, 1) ).toEqual(afterList); } testRemoveCounter(); console.log("All tests passing.."); /** "error" "TypeError: Cannot add/remove sealed array elements at removeCounter (fegewebemu.js:5:8) at testRemoveCounter (fegewebemu.js:15:10) at fegewebemu.js:17:1" */ console.clear(); const removeCounter= (list, index)=>{ return list.slice(0, index) .concat(list.slice(index+1)); } const testRemoveCounter = ()=>{ const beforeList = [0 ,10,20]; const afterList = [0, 20]; deepFreeze(beforeList); expect( removeCounter(beforeList, 1) ).toEqual(afterList); } testRemoveCounter(); console.log("All tests passing.."); // Passing
ES6:
console.clear(); const removeCounter= (list, index)=>{ return [ ...list.slice(0, index), ....list.slice(index + 1) ]; } const testRemoveCounter = ()=>{ const beforeList = [0 ,10,20]; const afterList = [0, 20]; deepFreeze(beforeList); expect( removeCounter(beforeList, 1) ).toEqual(afterList); } testRemoveCounter(); console.log("All tests passing.."); // Passing
Modify one element in array:
console.clear(); const incrementCounter = (list, index) => { list[index]++; return list; }; const testIncrementCounter = ()=>{ const beforeList = [0 ,10,20]; const afterList = [0, 11, 20]; deepFreeze(beforeList); expect( incrementCounter(beforeList, 1) ).toEqual(afterList); } testIncrementCounter(); console.log("All tests passing.."); /** "error" "Error: Expected [ 0, 10, 20 ] to equal [ 0, 11, 20 ] at Object.assert [as default] (https://wzrd.in/standalone/expect@latest:489:9) at Expectation.toEqual (https://wzrd.in/standalone/expect@latest:70:26) at testIncrementCounter (fegewebemu.js:16:43) at fegewebemu.js:18:1" */ console.clear(); const incrementCounter = (list, index) => { let res = list.slice(0, index) .concat(++list[index]) .concat(list.slice(index+1)); return res; }; const testIncrementCounter = ()=>{ const beforeList = [0 ,10,20]; const afterList = [0, 11, 20]; deepFreeze(beforeList); expect( incrementCounter(beforeList, 1) ).toEqual(afterList); } testIncrementCounter(); console.log("All tests passing.."); // Passing
ES6:
console.clear(); const incrementCounter = (list, index) => { return [ ...list.slice(0, index), ++list[index], ...list.slice(index+1) ]; }; const testIncrementCounter = ()=>{ const beforeList = [0 ,10,20]; const afterList = [0, 11, 20]; deepFreeze(beforeList); expect( incrementCounter(beforeList, 1) ).toEqual(afterList); } testIncrementCounter(); console.log("All tests passing.."); // Passing
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2014-11-29 [AngularJS] Accessing Scope from The Console
2014-11-29 [AngularJS] Accessing Data in HTML -- controllerAs, using promises
2014-11-29 [AngularJS] Directive Definition Objects (DDO)
2014-11-29 [AngularJS] Using the Angular scope $destroy event and method