關於javascript的深拷貝淺拷貝 思考

西南_張家輝發表於2018-02-07

目錄:

  • 深拷貝,淺拷貝

    • 什麼是複製?

      • 簡單變數的複製,記憶體小,我們直接複製不會發生引用。
      • 首先深複製和淺複製只針對像 Object, Array 這樣的複雜物件的。簡單來說,淺複製只複製一層物件的屬性,而深複製則遞迴複製了所有層級。
    • 下面是一個簡單的淺複製

      • 淺複製只會將物件的屬性依次複製,而不會進行遞迴,而 javascript 儲存物件都是村地址的,淺複製就是將 obj.arr 和 shallowObj.arr 指向同一個記憶體地址
      var obj = { a:1, arr: [2,3] };
      var shallowObj = shallowCopy(obj);
      
      function shallowCopy(src) {
        var dst = {};
        for (var prop in src) {
          if (src.hasOwnProperty(prop)) {
            dst[prop] = src[prop];
          }
        }
        return dst;
      }
      複製程式碼

      image

      • 當我們測試的時候就會發現這樣的結果
      shallowObj.arr[1] = 5;
      obj.arr[1]   // = 5
      複製程式碼
    • 下面是一個深複製的例子

      • 深複製的原理上面提到了,我們直接來看程式碼。
      var obj = { a:1, arr: [1,2] };
      var obj2 = deepCopy(obj);
      
      複製程式碼

      image

    • 下面來討論普遍的深淺複製的幾種實現方法

      • ES6 使用兩種複製方法不會發生引用

        • array2 = Array.form(array1)
        • array2 = [...array1];
      • 基本的 js 陣列和 json 複製

        • array2 = array1.slice(0)
        • array2 = array1.concat()
        //迴圈複製
        for(var i = 0;i < arr1.length; i++){
            arr2[i] = arr1[i];
        }
        
        //json資料
        for(var name in json1){
            json2[name] = json1[name];
        }
        複製程式碼
      • 淺複製的幾種方法

        var json1 = {"a":"panda","arr1":[1,2,3]}
        function copy(obj1) {
            var obj2 = {};
        &emsp;&emsp;for (var i in obj1) {
        &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;obj2[i] = obj1[i];
        &emsp;&emsp;}
            return obj2;
        }
        var json2 = copy(json1);
        json1.arr1.push(4);
        alert(json1.arr1);  //1234
        alert(json2.arr1)  //1234
        複製程式碼
      • 深複製的幾種方法

        
        //簡單粗暴的深複製
        //劣勢:無法複製函式
        //原型鏈沒了,物件就是object,所屬的類沒了。
        function jsonClone(obj) {
            return JSON.parse(JSON.stringify(obj));
        }
        var clone = jsonClone({ a:1 });
        ---------------
        var json1={"name":"panda","age":18,"arr1":[1,2,3,4,5],"string":'afasfsafa',"arr2":[1,2,3,4,5],"arr3":[{"name1":"panda"},{"job":"前端開發"}]};
        var json2={};
        
        function copy(obj1,obj2){
          var obj2=obj2||{}; //最初的時候給它一個初始值=它自己或者是一個json
          for(var name in obj1){
            if(typeof obj1[name] === "object"){ //先判斷一下obj[name]是不是一個物件
              obj2[name]= (obj1[name].constructor===Array)?[]:{}; //我們讓要複製的物件的name項=陣列或者是json
              copy(obj1[name],obj2[name]); //然後來無限呼叫函式自己 遞迴思想
            }else{
              obj2[name]=obj1[name];  //如果不是物件,直接等於即可,不會發生引用。
            }
          }
          return obj2; //然後在把複製好的物件給return出去
        }
        json2=copy(json1,json2)
        json1.arr1.push(6);
        alert(json1.arr1);  //123456
        alert(json2.arr1);  //12345
        
        複製程式碼

參考了:

深入剖析 JavaScript 的深複製

js中物件的複製,淺複製(淺拷貝)和深複製(深拷貝)

你不知道的 javascript (上)

歡迎來我的主頁和留言探討問題

lpove.github.io/hexo/

相關文章