iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 14
0
Modern Web

寫JS30天系列 第 14

JS 30 - 14 - Reference Copy or Value Copy

  • 分享至 

  • xImage
  •  

call by value

在js中,基本型別的number、variable、

function exchangeNum(a, b) {
  let cachedNum;
  cachedNum = a;
  a = b;
  b = cachedNum ;
  console.log(`a為${a}`); //20
  console.log(`b為${b}`); //10
}

let num1 = 10;
let num2 = 20;

exchangeNum(num1, num2);

console.log(`num1為${num1}`); //10
console.log(`num2為${num2}`); //20

寫一個function,將兩個數字帶入參數
不會影響到外面的變數num1,num2
意思是複製一份 10 和 20 存在新的記憶體位置
放進入function exchangeNum(a, b)去使用

這個就是call by value

在codepen打開number範例;
在codepen打開string範例;
在codepen打開boolean範例;

結論:基本型別使用call by value

function exchangeArray(a, b) {
  let cachedArr;
  cachedArr = a;
  a = b;
  b = cachedArr;
  console.log(`a為${JSON.stringify(a)}`); //[ 5, 6, 7, 8]
  console.log(`b為${JSON.stringify(b)}`); //[ 1, 2, 3, 4]
}

let arr1 = [1, 2, 3, 4];
let arr2 = [5, 6, 7, 8];

exchangeArray(arr1, arr2);

console.log(`arr1為${JSON.stringify(arr1)}`); //[ 1, 2, 3, 4]
console.log(`arr2為${JSON.stringify(arr2)}`); //[ 5, 6, 7, 8]

如果將aray當成一個整體,將兩個array進行互換,
結果如同call by value

在codepen打開array本身互換範例;

call by reference

單是如果對array內的element進行互換,
結果會有所不同

function exchangeArray(a, b) {
  let cachedNum;
  cachedNum = a[0];
  a[0] = b[0];
  b[0] = cachedNum;
  console.log(`a為${JSON.stringify(a)}`); //[ 5, 2, 3, 4]
  console.log(`b為${JSON.stringify(b)}`); //[ 1, 6, 7, 8]
}

let arr1 = [1, 2, 3, 4];
let arr2 = [5, 6, 7, 8];

exchangeArray(arr1, arr2);

console.log(`arr1為${JSON.stringify(arr1)}`); //[ 5, 2, 3, 4]
console.log(`arr2為${JSON.stringify(arr2)}`); //[ 1, 6, 7, 8]

將arr1和arr2內的第一個element(index === 0)互換
除了a, b的兩個array會被置換
連function外面的arr1和arr2也受影響
在codepen打開array內element互換範例;

function objectContentChange(a) {
  let cachedObj;
  cachedObj = a;
  a.name = "Kai";
  a.age = 25;
  console.log(`a為${JSON.stringify(a)}`); //"a為{'name':'Kai','age':25}"
}

let obj1 = {
  name: "Jason",
  age: 29
};
;

objectContentChange(obj1);

console.log(`obj1為${JSON.stringify(obj1)}`); //"obj1為{'name':'Kai','age':25}"

用一個function的參數a,帶入obj1修改object的內容name和age
除了a會修改其內容,function外的obj1的內容也會跟著修改。

在codepen打開object內element修改範例;
結論:array和object兩個複合型別,當指派給一個新的變數時,修改新的變數的內容,原本的array或object的內容也會被修改

但是有那麼簡單嗎?

call by sharing

let Jason = {
  name: "Jason",
  age: 29,
  car: ["volvo", "Kymco"]
}

function changePerson(obj) {
  obj = {
  name: "Kai",
  age: obj.age - 5,
  car: ["volvo", "Kymco", "benz"]
}
  
  console.log(obj); // { name: "Kai", age: 25, car: ["volvo", "Kymco", "benz"]}

}

changePerson(Jason);
console.log(Jason);// { name: "Jason", age: 29, car: ["volvo", "Kymco"]}

在codepen打開;

如果將要複製的object一個新的變數obj,用一個新的變數obj來改變object
外面的Jason物件則不會被改變
因此有人稱之為call by sharing

因此在JS中
基本型別為call by reference
複合型別為call by sharing

參考資料
完整程式碼


上一篇
JS 30 - 13 - Slide in on Scroll
下一篇
JS 30 - 15 - Local Storage
系列文
寫JS30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言