js 數組對象深拷貝

結論:對象的拷貝不能採用直接賦值的方式。html

背景

踩過的坑以下:git

formData原本是父組件傳過來的,可是我不想直接用,因而我直接賦值給一個formDataCopy的對象。github

可是詭異的事情發生了,就是在我填寫本身的表單組件的時候,一旦表單的數據發生的變化時,原本是formDataCopy的值發生變化,可是‘formDataDefault值’ 這個字符串卻被打印出來,也就是說formData改變了。正則表達式

奇怪,formData是父組件傳過來的值怎麼會改變呢?數組

通過一番掙扎,才發現formDataCopy使用的是簡單的賦值,致使formDataCopy和formData指向相同的對象。函數

formDataCopy一改變,formData就會跟着變。ui

以上是背景,因此我就對淺拷貝和深拷貝進行了總結:spa

淺拷貝

什麼是淺拷貝:二者是指向一個對象。code

對象的淺拷貝

一、對象的直接遍歷賦值。orm

二、ES6中的 var copyObj = Object.assign({}, obj);

三、ES7擴展運算符 var copyObj = { ...obj }

四、Jquery淺拷貝 var copiedObject = jQuery.extend({}, originalObject) 若是改變了originalObject,copiedObject 也會變。

數組的淺拷貝

(二者指向不一樣的對象,可是隻能拷貝一層)

  • array.concat();
  • array.slice(0);

若是該元素是個對象引用 (不是實際的對象),slice 會拷貝這個對象引用到新的數組裏。兩個對象引用都引用了同一個對象。若是被引用的對象發生改變,則新的和原來的數組中的這個元素也會發生改變,因此是淺拷貝。

對於字符串、數字及布爾值來講(不是 String、Number 或者 Boolean 對象),slice 會拷貝這些值到新的數組裏。在別的數組裏修改這些字符串或數字或是布爾值,將不會影響另外一個數組。

也就是說,若是原數組改變的是基本數據類型,好比String,Boolean,Number的數據,不會影響到新數組; 可是若是改變的是對象或者數組中的數據,是會影響到新數組的,也也就是對於對象或者數組,新舊數組指向的是一個對象。

深拷貝

(下面說的深拷貝是基本對象的深拷貝,不考慮對象的複雜屬性,好比set,get,Function等)

一、最簡單的方式 JSON.parse(JSON.stringify(Obj)) 這種方法使用較爲簡單,能夠知足基本的深拷貝需求,並且可以處理JSON格式能表示的全部數據類型,可是對於正則表達式類型、函數類型等沒法進行深拷貝(並且會直接丟失相應的值)。

二、jQuery深拷貝 var copiedObject = $.extend(true, {}, originalObject)

三、手動寫遞歸方式

var array = [
   { number: 1 },
   { number: 2 },
   { number: 3 }
];
function copy (obj) {
        var newobj = obj.constructor === Array ? [] : {};
        if(typeof obj !== 'object'){
            return;
        }
        for(var i in obj){
           newobj[i] = typeof obj[i] === 'object' ? copy(obj[i]) : obj[i];
        }
        return newobj
}
var copyArray = copy(array)
copyArray[0].number = 100;
console.log(array); // [{number: 1}, { number: 2 }, { number: 3 }]
console.log(copyArray); // [{number: 100}, { number: 2 }, { number: 3 }]
複製代碼

參考文檔

www.cnblogs.com/penghuwan/p…

github.com/wengjq/Blog…

相關文章
相關標籤/搜索