为了转生而点技能-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

<<:  【Python SQL : 数据持久化 攻略】SQLite x MySQL x SQLAlchemy

>>:  Python 学习笔记_装饰器(decorator) 与重试(retry)

APP 开发 组别

APP 开发 组别 https://wolkesau.medium.com/app-开发-组别-49...

Ruby on Rails Route 起步走

举个例⼦来说,这个网址: http://rubyonrails.com/posts/123 Rail...

[Day 29]用Django架构建置专属的LINEBOT吧 - LIFF(II)Django Template样板

Django的Template(样板) 在Django专案刚建立的时候, 我们可以从views.py...

Day30 Redux基础练习

以下用to do list作为练习。 Actions Action是一般的JavaScript物件。...

完赛 != 完结

完赛感言 不知不觉才没有不知不觉,每天都在想着放弃,但最後还是撑到完赛,回想这三十天铁人赛的挣扎旅程...