乐趣区

关于前端:JavaScript深浅拷贝

咱们晓得,JavaScript 的数据类型分为根本数据类型和援用型数据类型。

对于根本数据类型而言,并没有深浅拷贝的区别,这里所说的深浅拷贝是针对援用型数据类型的。

浅拷贝:

 只是简略的复制(赋值),不会开拓新栈,复制的后果是两个对象都指向同一个地址,批改任意一个对象的属性,另外一个对象的属性也跟着该扭转。```
    const = originArray = [1,2,3,4,5];
    const = originObj = {a:'a',b:'b',c:[1,2,3]};
    
    const cloneArray = originArray;
    const cloneObj = originObj;
    
    console.log(cloneArray);    //[1,2,3,4,5]
    console.log(originObj); //{a:'a',b:'b',c:Array[3]}
    
    cloneArray.push(6);
    cloneObj.a = {aa:'aa'};
    
    console.log(cloneArray);    //[1,2,3,4,5,6]
    console.log(originArray);   //[1,2,3,4,5,6]

    console.log(cloneObj);  //{a:{aa:'aa'},b:'b',c:Array[3]}
    console.log(originObj); //{a:{aa:'aa'},b:'b',c"Array[3]} 
```   

深拷贝:

 开拓新栈,两个对象对应两个不同的地址,扭转其中一个对象的属性,另外一个对象的属性不产生扭转。

深拷贝的实现办法:

1、利用 JSON 对象中的 parse 和 stringfy
2、利用递归来实现每一层都从新创建对象并赋值

JSON.stringfy(); 将一个 JavaScript 值转为一个 JSON 字符串
JSON.parse(); 是将一个 JSON 字符串转成一个 JavaScript 值或对象
 第一种办法实现:const originArray = [1,2,3,4,5];
    const cloneArray = JSON.parse(JSON.stringfy(originArray));
    console.log(cloneArray === originArray);//false
    
    const originObj = {a:'a',b:'b',c:[1,2,3]};
    const cloneObj = JSON.parse(JSON.stringfy(originObj));
    console.log(cloneObj === originObj);//false
    
    cloneObj.a = 'aa';
    cloneObj.c = [1,1,1];
    
    console.log(cloneObj);  //{a:'a',b:'b',c:[1,1,1]}
    console.log(originObj); //{a:'a',b:'b',c:[1,2,3]}
    
    然而这种办法并不欠缺,undefined、function、symbol 会在转换过程中被疏忽。如果对象中有函数时,就不能用这个办法进行深拷贝。第二种办法实现:function deepClone(source){const targetObj = source.constructor === Array ? []:{}; // 判断复制的指标是对象还是数组
        for(let keys in source){if(source.hasOwnProperty(keys)){if(source[keys] && typeof source[keys] === 'object'){   // 如果值是对象,就递归一下
                    targetObj[keys] = source[keys].constructor === Array?[]:{};
                    targetObj[keys] = deepClone(source[keys]);
                
                }else{  // 如果不是,就间接赋值
                    targetObj[keys] = source[keys];
                }
            }
        }
        return targetObj;
    }
    
    const originObj = {
        name:'xiaochaochao',
        say:function(){console.log('hello world');
        }
    }
    console.log(originObj); //{name:'xiaochaochao',say:f}
    const cloneObj = deepClone(originObj);
    console.log(cloneObj);//{name:'xiaochaochao',say:f}

JavaScript 中的拷贝 (都是 浅拷贝):

concat();   slice();
es6 新增的 obj.assign(); ...( 扩大运算符)

总结:

1、赋值运算符进行的是浅拷贝
2、JavaScript 中的四种办法看起来是深拷贝,但其实是浅拷贝
3、JSON.stringfy 是深拷贝
4、递归能够实现全副的深拷贝


退出移动版