深拷贝和浅拷贝

67 阅读1分钟

浅拷贝:在堆内存中创建内存,拷贝前后基本数据类型相互间不受影响,但引用类型会共享同一块内存,会相互影响。浅拷贝只能拷贝一层,如果对象有更深的层次就会互相影响。

深拷贝:从堆内存中开辟一个新的区域存放对象,所有类型相互间都不受影响。

实现浅拷贝的方法

1. Object.assign()

Object.assign(target, ...sources);
//target 为你要拷贝到的对象
//后面为一个或多个源对象,后者会被前者覆盖
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
let target = {};

Object.assign(target, obj1, obj2);
console.log(target); // 输出: { a: 1, b: 3, c: 4 }

2. 展开运算符…

他可以拷贝第一层,后续的就不行了

let obj1 = { name: 'Kobe', address:{x:100,y:100}}
let obj2= {... obj1}
obj1.address.x = 200;
obj1.name = 'wade'
console.log('obj2',obj2) // obj2 { name: 'Kobe', address: { x: 200, y: 100 } }

深拷贝的实现方式

1. 手撕

map的作用是为了解决循环嵌套的问题

//Deep Clone
function deepClone(target, map = new WeakMap()) {
    if (target && typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {}
        if (map.has(target)) {
            return map.get(target)
        }
        map.set(target, cloneTarget)
        for (let key in target) {
            cloneTarget[key] = deepClone(target[key], map)
        }
        // 处理 Symbol 属性
        const symbols = Object.getOwnPropertySymbols(target);
        for (const symbol of symbols) {
            cloneTarget[symbol] = deepClone(target[symbol], map);
        }

        return cloneTarget
    } else {
        return target
    }
}

2.lodash的_.cloneDeep

var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);// false