複製物件不含參考(deep-copy)

http://larry850806.github.io/2016/09/20/shallow-vs-deep-copy/

手動賦值(Shallow Copy)

把物件的參考賦予方式改用值的方式來傳遞,此時手動傳值的部分將會完全獨立。不過注意,在內層物件還是依據參考的方式傳遞。

for…in(Shallow Copy)

和手動賦值的方式接近,不過是使用for...in的語法將原本的物件屬性,傳到新的物件上,這種方式同上也是屬於淺層賦值。

var string1 = "";
var object1 = {a: 1, b: 2, c: 3};

for (var property1 in object1) {
  string1 = string1 + object1[property1];
}

console.log(string1);
// expected output: "123"

轉字串(屬於完全複製沒有深度限制。)

將物件轉換為一個不相干的字串,再將字串轉回物件,這種方式就會使兩個物件毫無關聯

使用套件

1.jQuery 套件中的 extend 可以複製物件,他也可以將加入參數使用深度複製 (deep copy)

let obj = {name: '王康寶', age:{child: 18}}
let copy = $.extend(true, {}, obj); //使用 jquery.extend
copy.name = '盧卡斯';
copy.age.child = 99; //更改 copy.age.child 的值
//輸出
console.log(obj);  //{name: "王康寶", age:{child: 18}}
console.log(copy); //{name: "盧卡斯", age:{child: 99}}

2.lodash

lodash 也有提供_.cloneDeep用來做 Deep Copy

let obj = {name: '王康寶', age:{child: 18}}
let copy = _.cloneDeep(obj);  //使用 lodash.cloneDeep
copy.name = '盧卡斯';
copy.age.child = 99; //更改 copy.age.child 的值
//輸出
console.log(obj);  //{name: "王康寶", age:{child: 18}}
console.log(copy); //{name: "盧卡斯", age:{child: 99}}

ES6

Object.assign,Object.assign 能處理深度,只有一層的物件,沒辦法做到真正的 深拷貝(Deep Copy), 不過如果要複製的物件只有一層的話可以考慮使用他。

ES6 的 Set, Map 都沒辦法直接用 JSON 這種方法複製,還有 Class new 出來的實體 prototype 也會消失

到底要 deepClone 到多完整,還是要看需求

let obj = {name: '王康寶', age:{child: 18}}
let copy = Object.assign({}, obj);
//更改 copy.name 的值
copy.name = '盧卡斯';
//輸出
console.log(obj);  //{name: "王康寶", age:{child: 18}}
console.log(copy); //{name: "盧卡斯", age:{child: 18}}

______________________________________________________________

https://kanboo.github.io/2018/01/27/JS-ShallowCopy-DeepCopy/

真的要完全複製一份還是乖乖遞迴到不是 Array / Object 慢慢複製會比較好

淺拷貝只複製指向某個物件的指標,而不複製物件本身,新舊物件還是共用同一塊記憶體

深拷貝會另外創造一個一模一樣的物件,新物件跟原物件不共用記憶體,修改新物件不會改到原物件。

實現深拷貝(Deep Copy)

  • Underscore: _.clone()

  • jQuery: $.clone() / $.extend()

  • lodash: _.clone() / _.cloneDeep()

  • 使用 JSON.parse(JSON.stringify(obj))

對陣列裡面新增物件屬性

let new_array = [];
this.arrayData.map( x =>
{
    new_array.push
    ({
        name: x.name,
        age: x.age,
        locale: "Taipei"
    });
});
this.arrayData = new_array;

results matching ""

    No results matching ""