--- tags: Javascript --- # JS淺層複製及深層複製 ## JS物件參考 講到淺層複製及深層複製就會提到JS的物件參考,在JS裡傳值(`Call by value`)是複製的,將num的值複製到`num2`的新記憶體區域,例如以下 ```javascript= var num = 1; var num2 = num; ``` 而物件(陣列,函式)是利用`call by reference`,來看範例 ```javascript= var people = {name: "Joe"}; var people2 = people; people2.name = "Amy"; console.log(people == people2); // true console.log(people); // {name: 'Amy'} console.log(people2); // {name: 'Amy'} ``` 可以看到上面的範例,`people2`是參考`people`的記憶體位置,所以在`people2`更改`name`的值時,也會更改到`people`的值,因為他們**指向同一個記憶體位置** 如要重新附值,需要使用以下 ```javascript= var people = {name: "Joe"}; var people2 = people; people2 = {name: "Amy"}; console.log(people == people2); // false console.log(people); // {name: 'Joe'} console.log(people2); // {name: 'Amy'} ``` 但在函式裡面重新賦值,外面的變數都不會變,所以就是屬於 pass by value。 ## 淺層複製 shallow copy 以下是淺層複製的範例,可以看到利用以下方法只能改變第一層,可以發現`members`都指向同個記憶體 ```javascript= var family = { name: 'Joe家', members: { father: '爸', mom: '媽', brother: '弟' } } var newFamily = {}; for (var key in family) { newFamily[key] = family[key]; } newFamily.name = "Amy家"; console.log(family === newFamily); // false newFamily.members.brother = "Timmy"; console.log(family, newFamily); ``` ### jQuery `var newFamily2 = jQuery.extend({}, family);` ### ES6 `var newFamily3 = Object.assign({}, family);` ## 深層複製 deep copy 先將物件轉成字串,再賦予給新變數,就可以將值複製到新的記憶體區域 ```javascript= var newFamily4 = JSON.parse(JSON.stringify(family)) newFamily4.name = "Amy家"; newFamily4.members.brother = "Timmy"; console.log(family === newFamily4); // false ```