javascript中的深度拷貝的實現過程及深拷貝的幾種方法。


  對於淺拷貝和深拷貝的區別簡單的說就是:淺復制會導致 obj 和 obj1 指向同一塊內存地址,大概的示意圖如下。而深復制一般都是開辟一塊新的內存地址,將原對象的各個屬性逐個復制出去。具體回答可參考https://www.zhihu.com/question/23031215  鄒潤陽的回答。

  這里主要講的是深拷貝整個函數是怎么實現的。

這里深拷貝的例子是參照妙味課堂上一節對象的引用中的,具體可以去妙味課堂看一下。

<script>
var obj1 = {
    a : { b : 10 }
};

/*function copy(obj){  //淺拷貝
    
    var newObj = {};
    
    for(var attr in obj){
        newObj[attr] = obj[attr];
    }
    
    return newObj;
    
}*/

function deepCopy(obj){  //深拷貝
    var newObj = {};

    if(typeof obj != 'object'){
        //console.trace();
        return obj;
    }
    
    for(var attr in obj){  

        newObj[attr] = deepCopy(obj[attr]); 
    }
    //console.trace();
    //console.log(newObj);
    return newObj;

    
}

var obj2 = deepCopy(obj1);//第一層循環為  obj2=deepCopy(obj1)----->newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})------->newObj[a]=
                          //第二層循環為  newObj[b]=deepCopy({b:10}[b])=deepCopy(10)=10------->newObj[b]=10------->return newObj={b:10}
                          //newObj[a]={b:10}------>return newObj=a:{b:10}

// obj2.a.b = 20;
alert(obj2.a.b);     //10
alert(obj1.a.b);  //10
</script>
View Code

主要是用了遞歸的思想:

obj2=deepCopy(obj1)----->調用deepCopy函數,傳入的參數是obj1.第一個if判斷是否是對象,如果是則執行下面的for/in循環,如果不是則返回obj。第一個obj1顯然是對象,所以執行for/in循環。得到的結果是:

  1. newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})----->再次調用deepCopy函數,傳入的參數是對象{b:10},執行for/in循環。得到的結果是:
  2. newObj[b]=deepCopy({b:10}[b])=deepCopy(10)-------->再調用deepCopy函數,傳入的參數是{10},不是對象,返回obj,也就是10,得到的結果是:
  3. newObj[b]=deepCopy({b:10}[b])=deepCopy(10)=10.

至此,整個“遞”的過程就完成了。下面是“歸”的過程。也就是一個相反的過程

  1. deepCopy(10)=10.  代入上面的第二步,執行for/in循環得到newObj[b]=10,然后return newObj={b:10}
  2. 代入上面的第一步,執行for/in循環得到newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})   deepCopy函數執行返回就是第一步的return newObj={b:10},所以newObj[a]={b:10},return newObj={a:{b:10}}

 在return newObj;上添加console.log(newObj);輸出結果如下:

可以看到的確是return了兩次。第一次為{b:10},第二次為{a:{b:10}}.

 

另一種實現是使用parse和stringify:

var a = {
    name : { age : 100 }
};

var str = JSON.stringify(a);

var b = JSON.parse(str);

b.name.age = 200;

alert( a.name.age ); //100
View Code
•如何其他瀏覽器做到兼容
–http://www.json.org/去下載json2.js
它能正確處理的對象只有 Number, String, Boolean, Array, 扁平對象,即那些能夠被 json 直接表示的數據結構。
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM