1. 程式人生 > >JS對象的引用,對象的拷貝

JS對象的引用,對象的拷貝

遞歸 func cnblogs div 無法拷貝 script keyword js對象 var

[Toc]

一、場景

除了基本類型跟null,對象之間的賦值,只是將地址指向同一個,而不是真正意義上的拷貝

將一個對象賦值給另外一個對象。

var a = [1,2,3];
var b = a;
b.push(4); // b中添加了一個4
alert(a); // a變成了[1,2,3,4]  

自定義對象

var obj = {a:10};
var obj2 = obj;
obj2.a = 20; // obj2.a改變了,
alert(obj.a); // 20,obj的a跟著改變  

這就是由於對象類型直接賦值,只是將引用指向同一個地址,導致修改了obj會導致obj2也被修改

二、淺拷貝

所以,我們需要封裝一個函數,來對對象進行拷貝,通過for in 循環獲取基本類型,賦值每一個基本類型,才能真正意義上的復制一個對象

var obj = {a:10};
function copy(obj){
    var newobj = {};
    for ( var attr in obj) {
        newobj[attr] = obj[attr];
    }
    return newobj;
}
var obj2 = copy(obj);
obj2.a = 20;
alert(obj.a); //10  

這樣就解決了對象賦值的問題。

三、深拷貝

但是這裏存在隱患,如果obj中,a的值不是10,而是一個對象,這樣就會導致在for in中,將a這個對象的引用賦值為新對象,導致存在對象引用的問題。

var obj = {a:{b:10}};
function copy(obj){
    var newobj = {};
    for ( var attr in obj) {
        newobj[attr] = obj[attr];
    }
    return newobj;
}
var obj2 = copy(obj);
obj2.a.b = 20;
alert(obj.a.b); //20  

因此,由於這個copy對象只是對第一層進行拷貝,無法拷貝深層的對象,這個copy為淺拷貝,我們需要通過遞歸,來拷貝深層的對象。將copy改造成遞歸即可

var obj = {a:{b:10}};
function deepCopy(obj){
    if(typeof obj != ‘object‘){
        return obj;
    }
    var newobj = {};
    for ( var attr in obj) {
        newobj[attr] = deepCopy(obj[attr]);
    }
    return newobj;
}
var obj2 = deepCopy(obj);
obj2.a.b = 20;
alert(obj.a.b); //10  

JS對象的引用,對象的拷貝