原文网址:JS--拷贝数组的方法(浅拷贝)_IT利刃出鞘的博客-CSDN博客
本文介绍JS拷贝数组的方法。
本文介绍的拷贝方式都是浅拷贝,拷贝的是引用。如果数组是一维数组,而且里边都是基本元素(比如:字符串、数字),那么拷贝后的数组和原来数组数据是相互独立的,修改其中一个数组不会影响原来数组。如果数组是二维数组或者是对象数组,那么拷贝后的数组和原来数组数据不是相互独立的,修改其中一个数组会影响原来数组。
自从ES6出现以来,这已经成为最流行的方法。它是一个很简单的语法,但是当你在使用类似于React和Redux这类库时,你会发现它是非常非常有用的。
- numbers = [1, 2, 3];
- numbersCopy = [...numbers];
这个方法不能有效的拷贝多维数组。数组/对象值的拷贝是通过引用而不是值复制。
- numbersCopy.push(4);
- console.log(numbers, numbersCopy);
- // [1, 2, 3] and [1, 2, 3, 4]
- // 只修改了我们希望修改的,原数组不受影响
- nestedNumbers = [[1], [2]];
- numbersCopy = [...nestedNumbers];
- numbersCopy[0].push(300);
- console.log(nestedNumbers, numbersCopy);
- // [[1, 300], [2]]
- // [[1, 300], [2]]
- // 由于公用引用,所以两个数组都被修改了,这是我们不希望的
concat将数组与值或其他数组进行组合。
- [1, 2, 3].concat(4); // [1, 2, 3, 4]
- [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]
如果我们不指定参数或者提供一个空数组作为参数,就可以进行浅拷贝。
- [1, 2, 3].concat(); // [1, 2, 3]
- [1, 2, 3].concat([]); // [1, 2, 3]
同样的,处理对象和数组的时候是引用而不是值复制。
可以将任何可迭代对象转换为数组。给一个数组返回一个浅拷贝。
- console.log(Array.from('foo'))
- // ['f', 'o', 'o']
-
- numbers = [1, 2, 3];
- numbersCopy = Array.from(numbers)
- // [1, 2, 3]
同样的,处理对象和数组的时候是引用而不是值复制。
map源于数学,是将一个集合转换成另一种集合,同时保留结构的概念。
在英语中,它意味着Array.map 每次返回相同长度的数组。
- numbers = [1, 2, 3];
- double = (x) => x * 2;
-
- numbers.map(double);
当我们使用map方法时,需要给出一个callback函数用于处理当前的数组,并返回一个新的数组元素。
和拷贝数组有什么关系呢?
当我们想要复制一个数组的时候,只需要在map的callback函数中直接返回原数组的元素即可。
- numbers = [1, 2, 3];
- numbersCopy = numbers.map((x) => x);
如果你想更数学化一点,(x) => x叫做恒等式。它返回给定的任何参数。
- identity = (x) => x;
- numbers.map(identity);
- // [1, 2, 3]
同样的,处理对象和数组的时候是引用而不是值复制。
slice 方法根据我们指定的start、end的index从原数组中返回一个浅拷贝的数组。
- [1, 2, 3, 4, 5].slice(0, 3);
- // [1, 2, 3]
- // Starts at index 0, stops at index 3
-
- // 当不给定参数时,就返回了原数组的拷贝
- numbers = [1, 2, 3, 4, 5];
- numbersCopy = numbers.slice();
- // [1, 2, 3, 4, 5]
同样的,处理对象和数组的时候是引用而不是值复制。
Array.filter方法同样会返回一个新数组,但是并不一定是返回同样长度的,这和我们的过滤条件有关。
- [1, 2, 3].filter((x) => x % 2 === 0)
- // [2]
当我们的过滤条件总是true时,就可以用来实现拷贝。
- numbers = [1, 2, 3];
- numbersCopy = numbers.filter(() => true);
- // [1, 2, 3]
同样的,处理对象和数组的时候是引用而不是值复制。
其实用reduce来拷贝数组并没有展示出它的实际功能,但是我们还是要将其能够拷贝数组的能力说一下的
- numbers = [1, 2, 3];
- numbersCopy = numbers.reduce((newArray, element) => {
- newArray.push(element);
- return newArray;
- }, []);
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数,将其结果汇总为单个返回值。
上面我们的例子中初始值是一个空数组,我们在遍历原数组的时候来填充这个空数组。该数组必须要从下一个迭代函数的执行后被返回出来。
同样的,处理对象和数组的时候是引用而不是值复制。