[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?


發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *