[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
[Redux] Avoiding Array Mutations with concat(), slice(), and ...spread的更多相关文章
- [Redux] Avoiding Object Mutations with Object.assign() and ...spread
Learn how to use Object.assign() and the spread operator proposed for ES7 to avoid mutating objects. ...
- 数组方法concat & slice
掌握数组的操作方法: concat() / slice() concat() 语法: arrayObject.concat(arrayX,arrayY,....,arrayZ) 功能:用于连接两个或 ...
- 【译】Rust中的array、vector和slice
原文链接:https://hashrust.com/blog/arrays-vectors-and-slices-in-rust/ 原文标题:Arrays, vectors and slices in ...
- [Javascript] Array methods in depth - slice
Array slice creates a shallow copy of an array. In this lesson we cover, in detail, exactly what a ' ...
- JavaScript引用类型之Array数组的concat()和push()方法的区别
在javascript中,我们一般都只用push向数组的尾部插入新元素的,但是其实在javascript中还有另外一个方法和push一样,也是向数组尾部插入新元素的,但是他们之间却存在着一定的区别,当 ...
- (转)Array.prototype.slice.call自解
很多框架或者库里面都会有这句的使用,最多的还是通过Array.prototype.slice.call(arguments,0)把arguments这个伪数组转换为真正的数组.但为什么可以这么做,却一 ...
- 【Go入门教程2】内置基础类型(Boolean、数值、字符串、错误类型),分组,iota枚举,array(数值),slice(切片),map(字典),make/new操作,零值
这小节我们将要介绍如何定义变量.常量.Go内置类型以及Go程序设计中的一些技巧. 定义变量 Go语言里面定义变量有多种方式. 使用var关键字是Go最基本的定义变量方式,与C语言不同的是Go把变量类型 ...
- 【GoLang】GoLang 遍历 map、slice、array方法
代码示例: map1 := make(map[string]string) map1["a"] = "AAA" map1["b"] = &q ...
- 详解 Array.prototype.slice.call(arguments)
首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...
随机推荐
- Android设备 cocos2dx 骨骼动画注册事件播放音效,退到后台再返回黑屏问题
最近遇到一个cocos2dx 骨骼动画注册事件播放音效,在骨骼动画播放的时候,按HOME键退到桌面,再次打开游戏的时候,会黑屏. 解决办法如下,可能不是太完美,至少解决了大部分问题. 1.在org.c ...
- android - startActivity浅谈
当执行startActivity(Intent intent, Bundle options)函数的时候,应用程序不是直接呼叫另外一个Activity,而是将intent传进Android框架中.An ...
- 启动php-fpm时报错
[root@localhost ~]# /usr/local/php/sbin/php-fpm [06-Aug-2012 19:17:53] ALERT: [pool www] pm.min_spar ...
- UIGestureRecognizer手势识别
UIGestureRecognizer 1.#import "ViewController.h"2.3.@interface ViewController ()<UIGest ...
- 服务器之间socket传输单链接和多连接测试结果
今天做了一下测试,目的是看看局域网内服务器a,通过一个连接往服务器b传输数据,和通过多个连接传输的不同. 结果发现和多少个连接没关系,一个进程一个连接就能跑满网卡,只要write的时候够快,read的 ...
- Java学习----对象的构造
public class Teacher { private String teacherName; private String gendar; // 构造方法:初始化属性值,没有返回类型 publ ...
- bootstrap首页制作
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>我的 ...
- ftp文件操作
PHP FTP操作类( 上传.拷贝.移动.删除文件/创建目录 ) 2016-06-01 PHP编程 /** * 作用:FTP操作类( 拷贝.移动.删除文件/创建目录 ) */ class class_ ...
- DEDE在下载文件时会生成table
当我们在系统内容模型中添加附件类型字段时,前台需要用{dede:field name='字段名'/}来调用. 例如我在后台发布一篇文章,上传一个zip的附件,字段的时间内容是:'/uploads/so ...
- jquery easy ui 学习 (3) window 限制在父类窗体内
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...