Javascript系列之淺複製與深複製

定義

淺複製

若是複製引用,複製後的引用都是指向同一個對象的實例,彼此之間的操做會互相影響。javascript

深複製

深複製不是簡單的複製引用,而是在堆中從新分配內存,而且把源對象實例的全部屬性都進行新建複製,以保證深複製的對象的引用圖不包含任何原有對象或對象圖上的任何對象,複製後的對象與原來的對象是徹底隔離的。java

淺複製

數組淺複製

利用數組方法slice和concat返回新數組特性,進行復制。數組

var arr = [1,2,3];
var new_arr = arr.concat();
arr[0] = 'new';
console.log(new_arr);      //[1, 2, 3]

再來看一組狀況:this

var arr = [{name: 'haha'}, [1,2,3]];
var new_arr = arr.concat();
arr[0].name = "lily";
console.log(new_arr.name);      //"lily"

能夠看出,若是數組元素是基本數據類型,就會複製一份,互不影響,而若是是對象或者數組,就會只複製對象和數組的引用。code

擴展運算符

var obj = { name: "jack" };
var a = [1, 2];
var b = [3, obj];
a.push(...b);
a   // [1, 2, 3, {name: "jack"}]
a[3].name = "rose";
b   // [3, {name: "rose"}]

Object.assign

var obj = { name: "jack" };
var copyObj = Object.assign({}, obj);
obj.name = "rose";
copyObj   // {name: "rose"}

自定義淺複製

function shallowCopy(obj) {
    if (typeof obj !== 'object') return;
    var new_obj = obj instanceof Array ? [] : {};

    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            new_obj[key] = obj[key];
        }
    }
    return new_obj;
}
var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = shallowCopy(source);
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function }
source.child.name = "lily";
console.log(target.child.name);              //"lily"
source.name = "sam";
console.log(target.name);                   //"source"
source.arr[0] = 5;
console.log(target.arr);                   //"5,2,34"
source.setName = function() { console.log(this.name); };
console.log(target.setName );            //function(){ this.name = "haha";  }

由此能夠看出,此方法確實能夠複製object和array對象,但沒法進行深複製;可是能夠複製function。對象

深複製

對象深複製

利用JSON對象的parse和stringify方法。ip

var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = JSON.parse(JSON.stringify(source));
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr:[1,2,34] }
source.child.name = "lily";
console.log(target.name);              //"child"
source.arr[0] = 5;
console.log(target.arr);              //"1,2,34"

由此能夠看出,雖然此方法確實能夠複製object和array對象,而且進行了深複製,卻沒法複製function。內存

自定義深複製

function deepCopy(obj) {
    if (typeof obj !== 'object') return;
    var new_obj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            new_obj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return new_obj;
}
var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = deepCopy(source);
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function }
source.child.name = "lily";
console.log(target.child.name);              //"child"
source.name = "sam";
console.log(target.name);                   //"source"
source.arr[0] = 5;
console.log(target.arr);                   //"1,2,34"
source.setName = function() { console.log(this.name); };
console.log(target.setName );            //function(){ this.name = "haha";  }
相關文章
相關標籤/搜索