JS中深拷貝陣列 物件 物件陣列方法

2021-07-28 05:01:56 字數 3142 閱讀 6318

我們在js程式中需要進行頻繁的變數賦值運算,對於字串、布林值等可直接使用賦值運算子 「=」 即可,但是對於陣列、物件、物件陣列的拷貝,我們需要理解更多的內容。

首先,我們需要了解js的淺拷貝與深拷貝的區別。

我們先給出乙個陣列:

var arr = ["a","b"];

現在怎麼建立乙份arr陣列的拷貝呢?直接執行賦值運算嗎?我們來看看輸出結果

var arrcopy =arr;

arrcopy[1] = "c";

arr

//=> ["a","c"]

可以發現對拷貝陣列 arrcopy 進行操作時原陣列也相應地被改變了,這就是js的淺拷貝模式。所以我們可以指出對陣列、物件、物件陣列進行簡單賦值運算只是建立了乙份原內容的引用,指向的仍然是同一塊記憶體區域,修改時會對應修改原內容,而有時候我們並不需要這種模式,這就需要對內容進行深拷貝。

1 陣列的深拷貝

對於陣列的深拷貝常規的有三種方法:

方法一:遍歷複製

1

var arr = ["a", "b"], arrcopy =;

2for (var item in arr) arrcopy[item] =arr[item];

3 arrcopy[1] = "c";

4 arr //

=> ["a", "b"]

5 arrcopy //

=> ["a", "c"]

考慮偽多維陣列可以寫成函式形式:

function

arrdeepcopy(source)

這種方法簡單粗暴,但是利用js本身的函式我們可以更加便捷地實現這個操作。

方法二:slice()

呼叫格式為:

arrayobject.slice(start,end)
方法返回乙個新的陣列,包含從 start 到 end (不包括該元素)的 arrayobject 中的元素。該方法並不會修改陣列,而是返回乙個子陣列。

在這裡我們的思路是直接從陣列開頭截到尾:

arrcopy = arr.slice(0);

arrcopy[1] = "c";

arr

//=> ["a", "b"]

arrcopy //

=> ["a", "c"]

可以看出成功建立了乙份原陣列的拷貝。

方法三:concat()

呼叫格式為:

arrayobject.concat(arrayx,arrayx,......,arrayx)
該方法不會改變現有的陣列,而僅僅會返回被連線陣列的乙個副本。

使用這種方法的思路是我們用原陣列去拼接乙個空內容,放回的便是這個陣列的拷貝:

arrcopy =arr.concat();

arrcopy[1] = "c";

arr

//=> ["a", "b"]

arrcopy //

=> ["a", "c"]

2、物件的深拷貝

對於陣列的深拷貝我們有了概念,那麼一般物件呢?

我們給出乙個物件:

var obj = ;

同樣做測試:

var objcopy =obj;

objcopy.b = 3;

obj

//=>

objcopy //

=>

同樣,簡單的賦值運算只是建立了乙份淺拷貝。

而對於物件的深拷貝,沒有內建方法可以使用,我們可以自己命名乙個函式進行這一操作:

var objdeepcopy = function

(source);

for (var item in source) sourcecopy[item] =source[item];

return

sourcecopy;

}

但是對於複雜結構的物件我們發現這個函式並不適用,例如:

var obj = , "b": 2 };

所以需要進行一點修改:

var objdeepcopy = function

(source);

for (var item in source) sourcecopy[item] = typeof source[item] === 'object' ?objdeepcopy(source[item]) : source[item];

return

sourcecopy;

}var objcopy =objdeepcopy(obj);

objcopy.a.a1[1] = "a13";

obj

//=> , "b": 2 }

objcopy //

=> , "b": 2 }

3、物件陣列的深拷貝

如果再考慮更奇葩更複雜的情況,例如我們定義:

var obj = [, "b": 2 }, ["c", ]];

這是乙個由物件、陣列雜合成的奇葩陣列,雖然我們平時寫程式基本不可能這麼折騰自己,但是可以作為一種特殊情況來考慮,這樣我們就可以結合之前說的方法去拓展拷貝函式:

var objdeepcopy = function

(source) ;

for (var item in

source)

return

sourcecopy;

}var objcopy =objdeepcopy(obj);

objcopy[0].a.a1[1] = "a13";

objcopy[1][1].e = "6";

obj

//=> [, "b": 2 }, ["c", ]]

objcopy //

=> [, "b": 2 }, ["c", ]]

這樣它就可以作為乙個通用函式替我們進行深拷貝操作了。

JS中深拷貝陣列 物件 物件陣列方法

我們在js程式中需要進行頻繁的變數賦值運算,對於字串 布林值等可直接使用賦值運算子 即可,但是對於陣列 物件 物件陣列的拷貝,我們需要理解更多的內容。首先,我們需要了解js的淺拷貝與深拷貝的區別。我們先給出乙個陣列 var arr a b 現在怎麼建立乙份arr陣列的拷貝呢?直接執行賦值運算嗎?我們...

js中深拷貝陣列,物件,物件陣列方法

首先看看這邊講的 在js中,對於字串,布林值可直接使用賦值運算子就可以實現深拷貝,但對於引用型別,陣列,物件,物件陣列的拷貝呢,實際只是進行了淺拷貝 下面是乙個陣列 var arr a b 現在怎麼進行arr陣列的拷貝呢,直接賦值來的結果 var arrcopy arr arrcopy 1 c ar...

JS深拷貝陣列和物件

有時候在些js 時不小心直接給陣列和物件直接賦值,可能不會直接產生什麼 但若是遇到了奇怪的問題了,這很有可能就是在拷貝陣列或者物件時時進行淺拷貝,接受者在不知不覺地改變了某些元素的值,從而導致原始值就莫名其妙地被同步修改了 面對這種情況,最好對陣列或者物件進行深拷貝,為了不影響某些元素的丟失 比如某...