本篇文章主要介紹了JavaScript陣列和物件的複製的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧
一、資料型別
從狹義上來說,JS把所有的資料分成兩大類型:基本型別和參考型別,其中基本型別包括Undefined、Null、Boolean、Number和String,引用型別為Object,常用的 Array、Date、RegExp、Function等都屬於Object類別類型。
基本型資料和引用型資料的差異之一就是,在複製變數時,基本型資料複製獨立的一份新的拷貝,而引用型資料複製的是原始變數的引用。以下是一個例子:
// 基本类型数据的复制 var a = 10; var b = a; // b = 10 a = 20; // a = 20, b = 10 // 引用类型数据的复制 var m = [1, 2]; var n = m; m[0] = 10; console.log(n[0]); // 10
如果我想複製引用型別本身的值而非引用,顯然不能採用上面的方式。
二、陣列的淺複製
淺複製是指物件(陣列)被複製時,其引用欄位的值不會被複製,而是複製了對應欄位的引用。如:
var src = [ 'alpha', ['bravo', 'chalie'] ]; var dest = []; for (var i = 0; i < src.length; i++) { dest[i] = src[i]; } //此时,如果改变src中的引用字段,dest中相应的字段也会被改变 src[1].push('delta'); console.log(dest[1]); // ['bravo', 'chalie', 'delta']
淺複製一般用於一維數組,即數組中不存在引用類型的情況。常用的淺複製方法有:
concat方法
var src = ['alpha', 'bravo'], dest = []; dest = dest.concat(src);
concat方法比較多用在數組合併中,例如:
var a = ['alpha', 'bravo'], b = ['chalie', 'delta'], combine; combine = a.concat(b);
特別要指出,concat用於數組合併時,是將兩個(或多個)數組中的所有元素複製到新的對象,對於大型數組來說,開銷比較大。更好的方法是把後一個陣列的元素複製到前一個陣列中:
var src = ['alpha', 'bravo'], dest = ['chalie', 'delta']; Array.prototype.push.apply(src, dest);
#slice方法
##slice方法可以從已有數組中傳回選定的元素,傳回的是一個新數組。var src = ['alpha', 'bravo'], var dest = src.slice(0);
三、物件的淺複製
物件的淺複製可以用for-in遍歷來實現,在es6中提供了更為方便的Object.assign ()方法。var src = {name: 'fox', age: 20}, dest = null; dest = Object.assign({}, src);
jQuery中的$.extend,underscore中的_.extend等方法來實作物件的複製。
四、深度複製
淺複製的應用場景有限,更多情況下,我們希望能夠將物件複製出一個完整的副本,這就需要用到typeof或instanof運算子來對各個欄位的類型進行判斷。如果某個欄位是基本類型的,可以直接複製。如果某欄位是引用型別的,還需要對該欄位的所有欄位進行上述判斷,這就很容易讓我們考慮使用遞迴來實作這個功能。
function deep_copy(src, dest) { for (var p in src) { if (Array.isArray(src[p]) || src[p] instanceof Object) { dest[p] = Array.isArray(src[p]) ? [] : {}; arguments.callee(dest[p], src[p]); }else { dest[p] = src[p]; } } }
json大法:
function deep_copy_in_json(src) { return JSON.parse(JSON.stringify(src)); }
屬性在操作後會遺失,例如construtor屬性以及物件原型中的一些方法。
以上是JavaScript數組和物件的複製的程式碼實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!