11-2 Object, Array 淺複製與深複製
Lesson: 11-2 Object, Array 淺複製與深複製
11-2 Object, Array 淺複製與深複製
Original: https://course.andys.pro/Javascript-Intro/11-2-object-array-shallow-copy-and-deep-copy/
講義
1. 傳值 (Pass by Value) 與 傳址 (Pass by Reference)
在 JavaScript 中,變數如何「複製」取決於它的型別:
- 基本型別 (Number, String, Boolean):執行的是 傳值。複製時會產生一份完全獨立的副本。修改其中一個,另一個不會變。
- 複合型別 (Object, Array):執行的是 傳址。複製時只是複製了指向記憶體的「地址」。
2. 什麼是淺複製 (Shallow Copy)?
當你寫 arr2 = arr1 時,這就是淺複製。
- 特性:
arr1與arr2其實是共用同一個記憶體空間。 - 問題:如果你修改了
arr1的內容,arr2也會跟著被改變。
3. 什麼是深複製 (Deep Copy)?
如果你希望複製出來的物件/陣列是完全獨立、互不影響的,就必須進行深複製。
- 手動方式:逐一將原物件的每個屬性,指派給新物件的屬性。
- 迴圈方式:透過
for迴圈遍歷原陣列,將裡面的值一個一個push到新陣列中。var arr1 = [1, 2, 3]; var arr2 = []; for (var value of arr1) { arr2.push(value); // 一個一個傳,就會變成傳值 }
4. 小結
當你在開發時發現「明明只改了 A,結果 B 也跟著變了」,通常就是因為遇到了 淺複製 的問題。此時請考慮使用迴圈或其他深複製技巧來處理資料複製。
影片逐字稿 (AI 生成)
好,我們現在來看11-2,Object跟Array的複製那我們現在來看基本類型的複製然後我們再來了解什麼是ShallowCopy什麼是DeepCopyShallowCopy是淺複製,DeepCopy是深複製那我們來看一下好的,首先基本類型是NumberString和Bullet那它的複製怎麼複製呢?我先講Num1,它是123然後Num2是Num1然後當我改動Num1的時候Num2是不是還是它原本的值所以我改Num1不會改到Num2好的,可是當我們在做自傳的時候卻有一些神奇的事情發生了首先我有一個Array1,它是1234然後我把Array1傳給Array2那以我們以前的理解是不是說欸那Array1跟Array2應該是不同的Array可是我先去改Array欸,這個範例等一下,欸,這裡大家有發現嗎?大家有發現什麼事情嗎?他的…他的…他的…他的…他的…講…又又又又又這裡應該是Array他應該想要表達的意思是…這裡應該是…這裡應該是E吧對不對Array1的第一格他去改…Array1的第一格他去改5然後結果Array2也一起被修改到了好,這應該要寫一下等一下我說這個code我要跑…跑給大家看不然…就是沒有…沒有實際跑的話大家會…無法被說服12-1.js然後…好,然後我們這邊趕快VAR ARR1等於…123…幾個…4這邊是VAR ARR2然後是AR1傳進來然後這邊是LogAR1LogAR2然後這邊是…AR1的第一格等於5然後LogAR2然後我們去跑好,這邊我們會看到…結果是什麼123是123是這沒有問題嗎結果我去改…結果我改AR1結果AR2居然一起被改到了那這到底是…為什麼呢好,這我們會說這個東西是…潛複製就是說…你其實…你以為你傳給他的時候你改了其實實際上它…是…同樣一個記憶體空間OK在基本模式的時候就比如說像…這些什麼…Number啊String啊Booling啊它是直接…複製一次然後到另外一個記憶體去把它放進去所以它兩個實際上是指在不同的記憶體可是在這邊…等於是…指定…運算值的時候給AR2的時候其實它只是把…這個的…OBJ1它這個…的記憶體說…它是到哪裡所以實際上它們兩個是…會一起被修改會互相影響的OK它們的記憶體位置是…在一起的好…那…所以…有這個…就是有時候我們不希望就是…改第二個…Array的時候會被第一個影響到所以…我們就需要用到…Deep Copy那…如果我們用手動複製的話有一種方法就是說…我把它每一項…都怎樣Object1 AObject1 BObject1 C然後分別放進去這時候…我去改動第二個的…我去改動第二個的…把它改成一把那…它就不會被互相影響到或是我改動第一個我把第二個印出來就不會被影響到或者是我可以用回圈來做這件事情我可以把它一個一個讀出來對不對既然我們在…前面這個…基本型別一個一個單獨的放進去的時候是獨立的…把這個值拿出來複製一份再放到另外一個記憶體位置那我們是不是也可以用回圈來做到一樣的事情那我們改的時候就不會互相被影響好…那所以這個是…淺層複製和深層複製那這邊我趕快的…來把…這個手動複製…做給大家看因為我們還…講得蠻快的那這邊可以…就是…我說…這一張講得蠻快的所以…我們來做一次給大家看我們來看…之一…之二…之二…就是…好…這一次給大家看我來看…這個要看…就是…一分鐘…就是…真的…那是…那個可以…就…那是…我們來看…那是…那是…那是…那是…那…那是…那…那是…那是…那是…那是…那是…好,這邊我們先把他這樣都有,好,然後呢,再來是把第二個改變o1b對不對,他改成什麼改成100然後我們這邊去logobj1好,這時候他就只有改到什麼只有改到第二個而已,他沒有改到第一個或是說我去改第一個的b第一個b,就不會改到第二個OK,這是第一個做法手動的來做好,再來我們用回圈的做法做就這個他可以複製嗎可以,可以好,這邊他的做法就是他一個一個去把它push進去就把它push,push,push,push那這個寫法我們當然也可以就是寫更簡單嘛,對不對大家記得Fall off嗎Fall offFall off然後bpushi對不對好,這個先註解給他好這樣那你一個一個把它丟進去的話那他的結果應該是就是1,2,3,4那我如果去比如說我把a的第2個是5的話那我們這邊A有沒有,他只有改到這個嘛他不會去改到b嘛因為他是手動一個一個一個把值丟進去的這樣OK嗎這個叫做深度複製好的,那這邊是11-2好嗎好嗎好嗎好嗎好嗎好嗎
影片逐字稿largev2
好,我們現在來看11-2,Object跟Array的複製那我們先來看基本類型的複製然後我們再來了解什麼是Shallow Copy,什麼是Deep CopyShallow Copy是淺複製,Deep Copy是深複製那我們看一下好的,首先基本類型是Number,String和Boolean那它的複製怎麼複製呢我先講Num1,它是1,2,3然後Num2是Num1當我改動Num1的時候,Num2是不是還是它原本的值所以我改Num1不會改到Num2好的,可是當我們在做自串的時候卻有一些神奇的事情發生了首先我有一個Array1,它是1,2,3,4然後我把Array1傳給Array2那以我們以前的理解是不是說那Array1跟Array2應該是不同的Array可是我今天去改Array…這個範例等一下,欸?這裡大家有發現嗎?大家有發現什麼事情嗎?它的…這裡應該是要Array它應該想要表達的意思是這裡應該是這裡應該是1吧對不對Array1的第一格它去改Array1的第一格它去改5然後結果Array2也一起被修改到了也一起被修改到了這應該要寫一下我說這個code我要跑給大家看不然沒有實際跑的話大概會無法被說服12-1.js然後我們這邊趕快var arr1123幾個?41234然後這邊是var arr2然後是arr1傳進來然後這邊是logarr1arr2然後這邊是arr1的第一個等於5然後logarr2然後我們去跑這邊我們會看到結果是什麼?12341234這沒有問題嘛結果我去改我改arr1結果arr2居然一起被改到了那這到底是為什麼呢?我們會說這個東西是淺複製就是說你以為你傳給他的時候你改了其實實際上他是同樣一個記憶體空間在基本模式的時候就比如說像這些number string boolean他是直接複製一次然後到另外一個記憶體去把它放進去所以他兩個實際上是指的在不同的記憶體可是在這邊的等於是指定的運算值的時候給2的時候其實他只是把這個obj1的記憶體說他是到哪裡所以實際上他們兩個是會一起被修改會互相影響他們的記憶體位置是在一起的所以有這個就是有時候我們不希望就是改第二個array的時候會被第一個影響到所以我們就需要用到deep copy那如果我們用手動複製的話有一種方法就是說我把他每一項obj1aobj1b obj1c然後分別放進去這時候我去改動第二個的我去改動第二個的把它改成一版那他就不會被互相影響到或是我改動第一個我把第二個印出來就不會被影響到或者是我可以用回圈來做這件事情我可以把他一個一個讀出來既然我們在前面這個基本型別一個一個單獨的放進去的時候是獨立的把這個值拿出來複製一份再放到另外一個記憶體位置那我們是不是也可以用回圈來做到一樣的事情那我們改的時候就不會互相被影響那所以這個是淺層複製淺層複製和深層複製那這邊我趕快的來把這個手動複製做給大家看因為我們還講的蠻快的那這邊可以我說這張講的蠻快的所以我們來做一次給大家看蠻快的蠻快的好這邊我們先把他這樣都有再來是把第二個改OOE.B他改成什麼改成100然後我們這邊去logOBJ1J2好這時候他就只有改到只有改到第二個而已他沒有改到第一個或是說我去改第一個的B第一個的B就不會改到第二個OK這是第一個做法手動的來做好再來我們用回圈的做法就這個他可以複製嗎可以好這邊他的做法就是他一個一個去把他push進去就把他push那這個寫法我們當然也可以寫更簡單嘛大家記得falloff嗎fallofffalloffA然後B pushI好這先註解給大家這樣那你一個一個把他丟進去的話那他的結果應該是1234那我如果去比如說我把A的第二個是5的話那我們這邊A有沒有他只有改到這個嘛他不會去改到B嘛因為他是手動一個一個把紙丟進去的這樣OK嗎就是這個叫深度複製好的那這邊是11-2