JavaScript數(shù)組和對象的復(fù)制
一、數(shù)據(jù)類型
從狹義上來說,JS把所有的數(shù)據(jù)分成兩大類型:基本類型和引用類型,其中基本類型包括Undefined、Null、Boolean、Number和String,引用類型為Object,常用的Array、Date、RegExp、Function等都屬于Object類型。
基本型數(shù)據(jù)和引用型數(shù)據(jù)的區(qū)別之一就是,在復(fù)制變量時,基本型數(shù)據(jù)復(fù)制獨(dú)立的一份新的拷貝,而引用型數(shù)據(jù)復(fù)制的是原變量的引用。下面是一個例子:
// 基本類型數(shù)據(jù)的復(fù)制 var a = 10; var b = a; // b = 10 a = 20; // a = 20, b = 10 // 引用類型數(shù)據(jù)的復(fù)制 var m = [1, 2]; var n = m; m[0] = 10; console.log(n[0]); // 10
如果我想復(fù)制引用類型本身的值而非引用,顯然不能采用上面的方式。
二、數(shù)組的淺復(fù)制
淺復(fù)制是指對象(數(shù)組)被復(fù)制時,其引用字段的值不會被復(fù)制,而是復(fù)制了對應(yīng)字段的引用。如:
var src = [
'alpha',
['bravo', 'chalie']
];
var dest = [];
for (var i = 0; i < src.length; i++) {
dest[i] = src[i];
}
//此時,如果改變src中的引用字段,dest中相應(yīng)的字段也會被改變
src[1].push('delta');
console.log(dest[1]); // ['bravo', 'chalie', 'delta']
淺復(fù)制一般用于一維數(shù)組,即數(shù)組中不存在引用類型的情況。常用的淺復(fù)制方法有:
concat方法
var src = ['alpha', 'bravo'], dest = []; dest = dest.concat(src);
concat方法更多地被用在數(shù)組合并中,比如:
var a = ['alpha', 'bravo'], b = ['chalie', 'delta'], combine; combine = a.concat(b);
特別要指出,concat用于數(shù)組合并時,是將兩個(或多個)數(shù)組中的所有元素復(fù)制到新的對象,對于大型數(shù)組來說,開銷比較大。更好的辦法是把后一個數(shù)組的元素復(fù)制到前一個數(shù)組中:
var src = ['alpha', 'bravo'], dest = ['chalie', 'delta']; Array.prototype.push.apply(src, dest);
slice方法
slice方法可以從已有數(shù)組中返回選定的元素,返回的是一個新數(shù)組。
var src = ['alpha', 'bravo'], var dest = src.slice(0);
三、對象的淺復(fù)制
對象的淺復(fù)制可以用for-in遍歷來實(shí)現(xiàn),在es6中提供了更為方便的Object.assign()方法。
var src = {name: 'fox', age: 20},
dest = null;
dest = Object.assign({}, src);
也可以使用jQuery中的$.extend,underscore中的_.extend等方法來實(shí)現(xiàn)對象的復(fù)制。
四、深度復(fù)制
淺復(fù)制的應(yīng)用場景有限,更多情況下,我們希望能夠?qū)ο髲?fù)制出一個完整的副本,這就需要用到typeof或instanof操作符來對各個字段的類型進(jìn)行判斷。如果某字段是基本類型的,可以直接復(fù)制。如果某字段是引用類型的,還需要對該字段的所有字段進(jìn)行上述判斷,這就很容易讓我們考慮使用遞歸來實(shí)現(xiàn)這個功能。
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];
}
}
}
在上述代碼中,由于數(shù)組是特殊的對象,因此可以用for-in來遍歷。
另外,還可以使用json大法:
function deep_copy_in_json(src) {
return JSON.parse(JSON.stringify(src));
}
這樣做雖然比較簡便,但原對象的很多屬性在操作后會丟失,比如construtor屬性以及對象原型中的一些方法。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
- jQuery中json對象的復(fù)制方式介紹(數(shù)組及對象)
- JavaScript數(shù)組復(fù)制詳解
- JavaScript 數(shù)組的深度復(fù)制解析
- javascript 三種數(shù)組復(fù)制方法的性能對比
- Javascript 復(fù)制數(shù)組實(shí)現(xiàn)代碼
- javascript復(fù)制對象使用說明
- js中如何復(fù)制一個對象并獲取其所有屬性和屬性對應(yīng)的值
- 原生js實(shí)現(xiàn)復(fù)制對象、擴(kuò)展對象 類似jquery中的extend()方法
- 深入理解JavaScript中的對象復(fù)制(Object Clone)
- 改進(jìn)版通過Json對象實(shí)現(xiàn)深復(fù)制的方法
相關(guān)文章
微信小程序中如何實(shí)現(xiàn)動態(tài)改變SVG顏色和尺寸
SVG可被非常多的工具讀取和修改SVG與JPEG和GIF圖像比起來,尺寸更小,且可壓縮性更強(qiáng),下面這篇文章主要給大家介紹了關(guān)于微信小程序中如何實(shí)現(xiàn)動態(tài)改變SVG顏色和尺寸的相關(guān)資料,需要的朋友可以參考下2022-07-07
微信小程序 wx.login解密出現(xiàn)亂碼的問題解決辦法
這篇文章主要介紹了微信小程序 wx.login解密出現(xiàn)亂碼的問題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-03-03
TypeScript遍歷Array的方法(for,forEach,every)
本文主要介紹了TypeScript遍歷Array的方法(for,forEach,every),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
javascript中String對象的slice()方法分析
這篇文章主要介紹了javascript中String對象的slice()方法,以實(shí)例形式分析了slice()方法的定義、參數(shù)與具體用法,具有一定的參考借鑒價值,需要的朋友可以參考下2014-12-12
javascript實(shí)現(xiàn)修改微信分享的標(biāo)題內(nèi)容等
這篇文章主要介紹了javascript實(shí)現(xiàn)修改微信分享的標(biāo)題內(nèi)容等,需要的朋友可以參考下2014-12-12
TypeScript中的接口Interface詳解(對象類型的強(qiáng)大工具)
TypeScript中的接口是一個強(qiáng)大而靈活的特性,它為我們提供了一種清晰、簡潔的方式來定義對象的結(jié)構(gòu)和類型,通過使用接口,我們可以編寫更加健壯、可維護(hù)的代碼,這篇文章主要介紹了TypeScript中的接口(Interface):對象類型的強(qiáng)大工具,需要的朋友可以參考下2024-08-08

