iT邦幫忙

0

為了轉生而點技能-JavaScript,day8(淺筆記-物件之淺層複製與深層複製

物件複製:

淺層複製(shallow copy):僅被複製的一方能保留第一層的物件之值,但是當複製方變更了第二層物件之值,則被複製方也會連動變更。

原因:有任何一層的資料地址(address)相同,背後指向的值相同,兩個物件的操作就會互相影響。
第一種寫法:[key in]。

        var person3 = {
            name: '小名',
            money: '500',
            family: {
                dad: 'Tom',
                mom: 'Mary',
            }
        };
        var person4 = {};
        for (var key in person3) {
            person4[key] = person3[key];
        };
        person4.name = '大名';
        person4.family.dad = 'John';
        console.log(person3, person4);

第二種寫法:Object.assign

        var person3 = {
            name: '小名',
            money: '500',
            family: {
                dad: 'Tom',
                mom: 'Mary',
            }
        };
        var person4 = Object.assign({}, person3);
        person4.name = '大名';
        person4.family.dad = 'John';
        console.log(person3, person4);

結果:

當更動第一層屬性:name的值,被複製的一方並沒有更動屬性的值。
https://ithelp.ithome.com.tw/upload/images/20211127/20143762FPRne3ePsG.jpg
當更動第二層屬性:dad的值,被複製的一方一起更動。
https://ithelp.ithome.com.tw/upload/images/20211127/20143762bZCAxSdfrT.jpg


深層複製(deep copy):利用JSON.parse(JSON.stringify())的方式。

原理:JSON.stringify() 先轉成字串;而JSON.parse()再轉回原本的物件或陣列,彼此之間是兩個完全獨立,每一層的資料地址(address)都不同,相互不影響。
限制:陣列值/物件值內容不能包含 function 。

        var person3 = {
            name: '小名',
            money: '500',
            family: {
                dad: 'Tom',
                mom: 'Mary',
            }
        };
        var person4 = JSON.parse(JSON.stringify(person3));
        person4.name = '大名';
        person4.family.dad = 'John';
        console.log(person3, person4);

https://ithelp.ithome.com.tw/upload/images/20211127/20143762lSrp0Ou9O6.jpg
例外狀況:
undefined : 會連同 key 一起消失。
NaN : 會被轉成 null。
Infinity :會被轉成 null。
regExp : 會被轉乘 空 {}。
Date : 型別會由 Data 轉成 string。

const originalData = {
  undefined: undefined, // undefined values will be completely lost, including the key containing the undefined value
  notANumber: NaN, // will be forced to null
  infinity: Infinity, // will be forced to null
  regExp: /.*/, // will be forced to an empty object {}
  date: new Date('1999-12-31T23:59:59'), // Date will get stringified
};
const faultyClonedData = JSON.parse(JSON.stringify(originalData));

console.log(faultyClonedData.undefined); // undefined
console.log(faultyClonedData.notANumber); // null
console.log(faultyClonedData.infinity); // null
console.log(faultyClonedData.regExp); // {}
console.log(faultyClonedData.date); // "1999-12-31T15:59:59.000Z"

參考文章:

  1. [JS] 複製 Array / Object 的幾種常用方法(深/淺拷貝):https://eudora.cc/posts/210430/
  2. JS 中的淺拷貝 (Shadow copy) 與深拷貝 (Deep copy) 原理與實作:https://www.programfarmer.com/articles/javaScript/javascript-shallow-copy-deep-copy
  3. 如何写出一个惊艳面试官的深拷贝?:https://juejin.cn/post/6844903929705136141#heading-6

尚未有邦友留言

立即登入留言