JS中实现数组和对象的深拷贝和浅拷贝

时间:2023-01-23 19:52:02

数组的拷贝

  > 数组的深拷贝,两层
var arr = [[1,2,3],[4,5,6],[7,8,9]];

var arr2 = [];
循环第一层数组
for(var i=0,len=arr.length;i<len;i++){
  循环第二层数组
for(var k=0,lens=arr[i].length;k<lens;k++){
    把每一个数组的内容添加到数组2中 arr2.push(arr[i][k]); } } console.log(arr2);
//[1, 2, 3, 4, 5, 6, 7, 8, 9] console.log(arr===arr2); //false
  > 数组的浅拷贝,一层
var arr = [1,2,3,4,5,6,7,8];
var arr2 = [];
for(var i=0,len=arr.length;i<len;i++){
    arr2.push(arr[i]);
}

console.log(arr2);
console.log(arr===arr2);
  > 数组的深拷贝,三层
    var arr = [[1,2,3,[4,5]],[[6,7,8,9]],10,11];
    var arr2 = [];
    // 第一层循环
    for(var i=0,len=arr.length;i<len;i++){

     // 如果第一层不是数组则直接拷贝到数组2中
     if(typeof arr[i]!=="object"){
       arr2.push(arr[i]);
     }

// 第二层
        for(var k=0,len1=arr[i].length;k<len1;k++){
            // 判断第二层是否是数组,这里简单的判断力一下是不是对象,没有做处理。
            if(typeof arr[i][k]==="object"){
                // 如果是数组,继续循环此数组。
                for(var j=0,len2=arr[i][k].length;j<len2;j++){
                    arr2.push(arr[i][k][j]);
                }
            }else{
                // 不是数组就按照正常情况执行。
                arr2.push(arr[i][k]);
            }
            
        }
    }

    console.log(arr2); //[1, 2, 3, 4, 5, 6, 7, 8, 9,10,11]
    console.log(arr===arr2); //false    
  > 数组的深拷贝,无限层,正则版 1.0
    var arr = [[1,2,3,[4,5]],[[6,7,8,9]],10,11,12,13,[14,[15,16,17,[18,[19,[20]]]]]];
    var arr2 = [];
// 先把数组转换成字符串,然后将字符串里面的[]删除 var str = arr.toString().replace(/\[|\]/,""); console.log(str); //1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

// 将字符串转换成数组。 arr2 = str.split(",");
console.log(arr2); //["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] console.log(arr
===arr2); //false

  // 这样做的话简单了不少,而且扩展性比较强,但是现在出现了个bug,就是我们原本数组里面的是数字,现在变成了字符串,下面我们来解决一下这个问题。

  > 数组的深拷贝,无限层,正则版 2.0
    var arr = [[1,2,3,[4,5]],[[6,7,8,9]],10,11,12,13,[14,[15,16,17,[18,[19,[20]]]]],"a"];
    var arr2 = [];
// 先把数组转换成字符串,然后将字符串里面的[]删除 var str = arr.toString().replace(/\[|\]/,""); console.log(str); //1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

// 将字符串转换成数组。 arr2 = str.split(","); for(var i=0,len=arr2.length;i<len;i++){ // 判断是否可以转换成数字,如果可以则转换,否则不转换。 arr2[i] = parseFloat(arr2[i])||arr2[i]; } console.log(arr2); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, "a"] console.log(arr===arr2); //false

  虽然这里解决了上面的问题,但实际上还是有些问题的,就是如果arr1里面的数字原本就是字符串那么这个就有问题了,因为这个我们设置的是只要它可以转换成数字都将被转换。如果要解决这个问题的话,我们在将数组转换成字符串之前就要进行判断里面的内容是数字还是字符串,但是如果这样的话,我们用正则的方式将会变的非常麻烦,因为技术有限,只能解决到这里,如果你有好的方法,还请告知一下。

 

 对象的克隆和数组的克隆差不多,这里就不再说了,另外以前还写了一篇关于克隆方面的文章,有兴趣的话可以参考一下。

JS基础回顾,小练习(克隆对象,数组)