数组和对象深拷贝和浅拷贝

数组浅拷贝

1.原始循环放入新数组
2.arr.slice() 返回新数组
3.arr.concat() 返回新数组
4.[...arr] 扩展运算符
以上方法只能浅拷贝一维数组、(含对象的数组只能拷贝到对象的引用地址)

对象浅拷贝

浅拷贝之所以被称为浅拷贝,是因为对象只会被克隆最外部的一层,至于更深层的对象,则依然是通过引用指向同一块堆内存.
[...obj] 扩展运算符 浅拷贝
Object.assign 是浅拷贝

var a={
  obj:{a:'name'}
}
var c=Object.assign({},a)
c.obj.a='name111';
console.log(a)    //{"obj":{"a":"name111"}}

深拷贝 数组、对象值包含引用类型值的时候

JSON.parse( JSON.stringify());
这种简单粗暴的方法有其局限性。当值为undefinedfunctionsymbol 会在转换过程中被忽略。。。所以,对象值有这三种的话用这种方法会导致属性丢失。
存在的坑:
1.他无法实现对函数 、RegExp等特殊对象的克隆
2.会抛弃对象的constructor,所有的构造函数会指向Object
3.对象有循环引用,会报错

var arr = ['old', 1, true, ['a1', 'a2'], {num: 1}]
var new_arr = JSON.parse( JSON.stringify(arr) );

手写数组和对象 拷贝

浅拷贝

var shallowCopy = function(obj) {
    // 只拷贝对象
    if (typeof obj !== 'object') return obj;
    // 根据obj的类型判断是新建一个数组还是对象
    var newObj = obj instanceof Array ? [] : {};
    // 遍历obj,并且判断是obj的属性才拷贝
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

深拷贝方法
尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

function deepCopy(obj) {
  if (typeof obj == "object") {
        //复杂数据类型
       var result= Array.isArray(obj) ? [] : {};
        for (let i in obj) {
            result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i];
        }
        return result;
    } else {
        //简单数据类型 直接赋值
        return obj;
    }
}

你可能感兴趣的:(数组和对象深拷贝和浅拷贝)