js 的淺拷貝與深拷貝以及不一樣實現方式

舉兩個例子來講明淺拷貝與深拷貝

淺拷貝

// 淺拷貝
let origin = {
    p1: 1
};

let obj = {
    p2: 2,
    p3: {
        p4: 3
    }
};

let target = Object.assign(origin, obj);
console.log(target); // { p1: 1, p2: 2, p3: { p4: 3 } }
console.log(obj); // { p2: 2, p3: { p4: 3 } }

obj.p2 = 20;
console.log(target); // { p1: 1, p2: 2, p3: { p4: 3 } } target 的值並未修改
console.log(obj); // { p2: 20, p3: { p4: 3 } }

obj.p3.p4 = 30;
console.log(target); // { p1: 1, p2: 2, p3: { p4: 30 } } target 的值也被修改,說明覆制過來的 p3 的值只是一個引用
console.log(obj); // { p2: 20, p3: { p4: 30 } }

深拷貝

// 深拷貝
let obj1 = {
    p1: 1,
    p2: {
        p3: 2
    }
};

let obj2 = JSON.parse(JSON.stringify(obj1));

obj1.p2.p3 = 20;
console.log(obj2); // { p1: 1, p2: { p3: 2 } } p3的值並未隨着obj1的改變而改變

經過例子咱們能夠發現:對於源對象的引用類型,淺拷貝是對地址的複製,所以該地址的值改動後,源對象和拷貝對象的值都會改變。深拷貝是生成新的地址再拷貝值,源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另一個對象形成影響。es6

其餘不一樣實現方式

遞歸(深拷貝)

// 遞歸 (深拷貝)
function deepClone(target, source) {
    for (let key in source) {
        if (source[key] && typeof source[key] === 'object') {
            target[key] = source[key].construtor === Array ? [] : {};
            target[key] = deepClone(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return target;
}

let sObj = {
    p1: 1,
    p2: 'a',
    p3: {
        p4: 4
    },
    p5: [1, 2, 3, 4, 5]
}

let tObj = deepClone({ p6: 6 }, sObj);
sObj.p3.p4 = 40;
sObj.p5 = [2, 2, 2, 2];
console.log(tObj); // 值未改變 { p6: 6, p1: 1, p2: 'a', p3: { p4: 4 }, p5: { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 } }

es6 擴展運算符(淺拷貝)

// es6 的擴展運算符(淺拷貝)
let source = {
    p1: 1,
    p2: 'a',
    p3: {
        p4: 4
    }
}

let targetObj = {
    p5: 5,
    ...source
}

source.p3.p4 = 40;
console.log(targetObj); // 值改變 { p5: 5, p1: 1, p2: 'a', p3: { p4: 40 } }
相關文章
相關標籤/搜索