共勉~
在許多程式語言中,傳遞參數和賦值是透過值的直接複製或引用複製完成的。在JavaScript中,對於值是直接進行複製還是引用複製在語法上是沒有區別的,完全是根據值的類型來決定的。
在JavaScript中,簡單值總是透過值的直接複製來進行賦值傳遞的(null,undefined,字串,數字,布爾,symbol),而複合值(物件(包括數組等)和函數)總是透過引用複製的方式來進行賦值和傳遞的。
下面的範例可以加深理解:
var a = 1;var b = a; b++; a; //1b; //2var c = [1,2];var d = c; d.push(3); c; //[1,2,3]d; //[1,2,3]
#上面例子對於數組的賦值操作就是數組的淺拷貝,不難發現問題當一個數組改變的時候,其他賦值的數組也會改變,在很多類似備份的情況中,這並不是我們想要的結果。
var c = [1,2];var d = c; d.push(3); c; //[1,2,3]d; //[1,2,3]
我們可以透過兩種方法來實現數組的深拷貝:
var a = [1,2,3];var b = a.slice(0);var c = a.concat(); b.push(4); c.push(5); a; //[1,2,3]b; //[1,2,3,4]c; //[1,2,3,5]
相對來說陣列的拷貝比較簡單,而物件的淺拷貝我們也可以簡單實作:
function easyClone(Obj) {var objNew = {};for ( var i in Obj) { objNew[i] = Obj[i]; }return objNew; }
其實就是將每個原始物件的屬性和值複製到新對像上去,當然我們也可以使用Object.assign() 方法可以把任意多個的來源對象自身的可枚舉屬性拷貝給目標對象,然後返回目標對象,同時Object.assign()也是淺拷貝,有興趣的同學可以看看。
淺拷貝因為沒有遞歸循環檢查對象的每個值是否是對象,而是直接進行了賦值,所以如果某個值是對象的時候就會出現問題,所以在一般情況下我們需要用深拷貝來進行備份。
最簡單的深拷貝:
b = JSON.parse( JSON.stringify(a) )
限制:
無法複製函數
原型鏈沒了,物件就是object,所屬的類別沒了。
其實簡單的深拷貝只需要我們遞歸呼叫淺拷貝就可以了:
function deepCopy(obj) { var objNew = objNew || {}; for (var i in obj) { if (typeof p[i] === 'object') { objNew[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(obj[i], objNew[i]); } else { objNew[i] = obj[i]; } } return objNew; }
當然JQ的jQuery.extend()方法也可以做到深拷貝和淺拷貝:詳情可以參考這篇文章:
以上是JS數組和物件的淺拷貝和深拷貝教學講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!