由于数组不是js的基本类型,我们在对数组进行备份,如果只是简单的将它赋值给其他变量,那么我们只要改变其中任何一个,其他的变量的数组也会跟着改变。实际应用中就会产生bug
// 浅复制
var arr = ["one","two","three"];
var arrto = arr;
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // [1,"two","three"] ["one","two","three"]
改变数组arrto,arr也会受到影响,像这种直接赋值数组的方式就是浅复制,引发这种现象的原因是因为数组是引用数据类型,arrto = arr 是将arr数组的引用地址传递给了 arrto,arrto 与 arr 指向的是同一个数组。要避免这类情况发生我们可以 对数组进行深复制
// 深复制
var arr = ["one","two","three"];
var arrto = [];
for (var i = 0; i < arr.length; i++) {
arrto[i] = arr[i];
}
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
arr数组中的每个元素都是字符串,属于js的基本类型,可以直接传递值,遍历数组arr将数组中的每个元素传给新数组arrto就能实现数组的深复制。
使用一些js的函数也能实现数组的深复制
使用js内置函数实现深复制
1.slice 可以从已有的数组中返回选定的元素,且返回的是一个新数组
var arr = ["one","two","three"];
var arrto = arr.slice(0);
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
使用slice返回新数组后改变arrto的值,arr并未改变
2.concat : 连接两个或多个数组,返回新数组
var arr = ["one","two","three"];
var arrto = arr.concat([]);
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
3.map :返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。
var arr = ["one","two","three"];
var arrto = arr.map(ele=>ele);
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
总结:数组由于不是js的基本类型,不能进行直接传值,需要遍历数组的每一个基本类型的元素传值,最后构建新的数组。与数组类似 ,js的对象也直接复制也会产生与数组相同的问题,要实现深拷贝,需遍历对象的每个属性。