[JS] Pass By Sharing
一早和小夥伴被一個奇妙的問題給卡住,在 Parsing 資料我們經常使用 For 迴圈,每一次創建一個資料物件,並將其加入 Array,最後產出要的東西,#世界真美好。
可惜世界經常不是這樣運作。
我們知道都知道 Object 和 Array 是 Pass By Reference,所以如果沒有在迴圈中宣告新的物件,最後陣列裡的物件都會被改為最後一次迴圈的資料,像這樣:
const data = {
1: {id: 1, name: 'a'},
2: {id: 2, name: 'b'},
};
const resultArr = [];
const tempObj = {};
Object.keys(data).forEach(key => {
tempObj.id = data[key].id;
tempObj.name = data[key].name;
resultArr.push(tempObj);
})
console.log(resultArr);
/* output:
[
{id: 2, name: "b"},
{id: 2, name: "b"}
];
*/
當然啦,知道物件是 Pass By Reference,只要在 For 迴圈裡加入 let tempObj = {},讓每次執行時都創建一個物件,可以輕而易舉解決這個問題。
但這時突然一個異想天開,如果把 tempObj 在 For 迴圈中重新賦值會怎麼樣呢~
let data = {
1: {id: 1, name: 'a'},
2: {id: 2, name: 'b'},
};
const resultArr = [];
var tempObj = {};
Object.keys(data).forEach(key => {
tempObj = {};
tempObj.id = data[key].id;
tempObj.name = data[key].name;
resultArr.push(tempObj);
})
console.log(resultArr)
/* output:
[
{id: 1, name: "a"},
{id: 2, name: "b"}
];
*/
有些人把這樣的形式稱為 Pass By Sharing,一開始物件是指向同一個位置沒錯,但當把物件重新賦值時,就會指向新的物件,外面的物件不會受到影響。
更簡單的範例可以參考以下。
See the Pen Pass By Sharing by Winter (@yichinweng) on CodePen.
延伸閱讀:
1. 重新認識 JavaScript: Day 05 JavaScript 是「傳值」或「傳址」?
2. 深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?