摘要:使用方法拷贝数组打印新数组张小二新数组修改经过拷贝过的新数组隔壁张小二打印旧数组隔壁张小二打印新数组隔壁张小二结论使用方法拷贝数组,然后修改新数组,会改变旧数组的值。
一、原数组里的数据不包含引用类型
let arr1 = [1 , 2 , 3 , "hello" , "world"]; //原数组1、使用 slice() 方法
拷贝数组:
let arr2 = arr1.slice(0); console.log(arr2); //打印新数组 [1 , 2 , 3 , "hello" , "world"]; //新数组
修改经过 slice() 拷贝过的新数组:
arr2[3] = "Hello"; console.log(arr1); //打印旧数组 [1 , 2 , 3 , "hello" , "world"] console.log(arr2); //打印新数组 [1 , 2 , 3 , "Hello" , "world"]
结论:使用 slice() 方法拷贝数组,然后修改新数组,不会影响到旧数组的值。
2、使用 concat() 方法拷贝数组:
let arr3 = [].conat(arr1); console.log(arr3); //打印新数组 [1 , 2 , 3 , "hello" , "world"]; //新数组
修改经过 concat() 拷贝过的新数组
arr3[3] = "Hello"; console.log(arr1); //打印旧数组 [1 , 2 , 3 , "hello" , "world"] console.log(arr3); //打印新数组 [1 , 2 , 3 , "Hello" , "world"]
结论:使用 concat() 方法拷贝数组,然后修改新数组,不会影响到旧数组的值。
3、使用简单的数组赋值语法拷贝数组:
let arr4 = arr1; console.log(arr4); //打印新数组 [1 , 2 , 3 , "hello" , "world"]; //新数组
修改经过简单赋值过的新数组
arr4[3] = "Hello"; console.log(arr1); //打印旧数组 [1 , 2 , 3 , "Hello" , "world"] console.log(arr4); //打印新数组 [1 , 2 , 3 , "Hello" , "world"]
结论:使用数组简单赋值方法拷贝数组,然后修改新数组,会影响到旧数组的值。
原因:这种简单赋值的方法属于数组的浅拷贝,数组arr1和数组arr4共用同一块内存,其中一个数组改变,另一个数组也会跟着改变。
二、原数组里的数据包含引用类型let arr1 = [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}]; //原数组1、使用 slice() 方法
拷贝数组:
let arr2 = arr1.slice(0); console.log(arr2); //打印新数组 [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}]; //新数组
修改经过 slice() 拷贝过的新数组:
arr2[3].name = "隔壁张小二"; console.log(arr1); //打印旧数组 [1 , 2 , 3 , {"name" : "隔壁张小二"} , {"sex" : "male"}] console.log(arr2); //打印新数组 [1 , 2 , 3 , {"name" : "隔壁张小二"} , {"sex" : "male"}]
结论:使用 slice() 方法拷贝数组,然后修改新数组,会改变旧数组的值。
拷贝数组:
let arr3 = [].conat(arr1); console.log(arr3); //打印新数组 [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}]; //新数组
修改经过 concat() 拷贝过的新数组
arr3[3].name = "隔壁张小二"; console.log(arr1); //打印旧数组 [1 , 2 , 3 , {"name" : "隔壁张小二"} , {"sex" : "male"}] console.log(arr3); //打印新数组 [1 , 2 , 3 , {"name" : "隔壁张小二"} , {"sex" : "male"}]
结论:使用 concat() 方法拷贝数组,然后修改新数组,会改变旧数组的值。
1、数组的浅拷贝
(1)数组的直接赋值属于数组的浅拷贝,JS存储对象都是存内存地址的,所以浅拷贝会导致新数组和旧数组共用同一块内存地址,其中一个数组变化,另一个数组也会相应的变化。
(2)数组内部不含有引用类型,使用slice() 、concat() 和 assign() 方法都属于数组的深拷贝,一个数组变化,另一个数组不受影响。
(3)数组内部含有引用类型,使用slice() 、concat() 和 assign() 方法,非引用类型的值属于深拷贝,引入类型的值属于浅拷贝,一个数组变化,另一个也会相应的变化。
四、解决办法(含有引入类型的数组)方法一:递归
let cloneObj = function(obj){ let str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== "object"){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化对象 newobj = JSON.parse(str); //还原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === "object" ? cloneObj(obj[i]) : obj[i]; } } return newobj; }; let newArr = cloneObj(oldArr);
方法二:通过JSON解析解决
let newArr = JSON.parse(JSON.stringify(oldArr));
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/96382.html
摘要:函数的因为也拥有属性,所以其被称为类数组对象。方法数组的拼接,,指被拼接的对象数组,为数组。如果为负,则将其视为,其中为数组的长度。而提供了数组反转和排序来对数组进行重排序。用好原生,你的代码将显得干净,有趣。 前言 最近工作做数据交互展示,常和数据打交道,而随之而来的就是遇见后端传来的各种各样的数组,我需要用各式各样的方法来变换这些数据,来最好的展示这些数据;很多东西久了没用就容易忘...
摘要:深拷贝相比于浅拷贝速度较慢并且花销较大。所以在赋值完成后,在栈内存就有两个指针指向堆内存同一个数据。结果如下扩展运算符只能对一层进行深拷贝如果拷贝的层数超过了一层的话,那么就会进行浅拷贝那么我们可以看到和展开原算符对于深浅拷贝的结果是一样。 JS中数据类型 基本数据类型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用数据类型:...
摘要:前端芝士树浅拷贝深拷贝以及的作用首先还是得回到的基本数据类型。值类型深拷贝数值布尔值字符串。它接受任意数量的源对象,主要作用就是枚举它们的所有属性并分配给。 【前端芝士树】浅拷贝、深拷贝以及Object.assign()的作用 首先还是得回到Javascript的基本数据类型。 值类型[深拷贝]:数值Num、布尔值Boolean、字符串String、null、undefined。 基本...
阅读 4023·2022-09-16 13:49
阅读 1381·2021-11-22 15:12
阅读 1495·2021-09-09 09:33
阅读 1010·2019-08-30 13:15
阅读 1697·2019-08-29 15:30
阅读 610·2019-08-27 10:52
阅读 2624·2019-08-26 17:41
阅读 1857·2019-08-26 12:11