概念

  • 浅拷贝创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象

  • 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

浅拷贝

let obj = {
    id: 1,
    name: 'uzi',
    msg: {
        age: 5	
    }
}
let a = {};
for(let b in obj) {	// 浅拷贝, msg只拷贝了引用
    a[b] = obj[b];
}
a.msg.age = 18;	// obj.msg.age 也变为 18;
// ----------------------------------------------
Object.assign(a, obj);	// 复制对象,也是浅拷贝
// ---------------------------------------------
// 浅拷贝方法
function shallowCopy(source) {
    var target = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            target[i] = source[i];
        }
    }
    return target;
}
// -------------------------------------
// 展开运算符
let a = {...obj}

深拷贝

利用递归的方式实现深拷贝

// 乞丐版
function deepCopy(newObj, oldObj) {
    for(let k in oldObj) {
        // 判断属性值为什么类型
        let item = oldObj[k];
        if(item instanceof Array) { // 类型为数组时, 数组也是Object,所以写前面
            newObj[k] = [];
            deepCopy(newObj[k], item);
        } else if(item instanceof Object) {	// 类型为对象
            newObj[k] = {};
            deepCopy(newObj[k], item);
        } else {	// 简单数据类型
            newObj[k] = item;
        }
    }
}

完整优化参考如何写出一个惊艳面试官的深拷贝?

JSON.parse

let obj = {
    id: 1,
    name: 'uzi',
    msg: {
        age: 5	
    }
}
let obj1 = JSON.parse(JSON.stringify(obj));

这种方法虽然可以实现数组或对象深拷贝,但不能处理函数和正则,因为在使用JSON.stringify和JSON.parse处理后,得到的正则就不再是正则(变为空对象),得到的函数就不再是函数(变为null)。

函数库lodash的_.cloneDeep方法

jQuery.extend()方法


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

排序-JS版 上一篇
高阶函数与闭包 下一篇