0%

008重新認識JS-Day02-筆記4

基礎型別的更新與傳遞 (Pass by value)

我們在複製變數的時候,複製的也是該變數的「值」。
ex:

1
2
3
4
var a = 10;
var b = a;
console.log(a); // 10
console.log(b); // 10

以上這個例子,變數b的值是藉由複製變數a的值而來,
所以,就算變數a的值更改了,也不會影響到變數b的值。
像以上這種狀況,我們會稱作「傳值」(pass by value)。

物件型別的更新與傳遞 (Pass by address)

ex:

1
2
3
4
5
6
7
8
var ptr1 = {value:10};
var ptr2 = ptr1;
console.log(ptr1.value); // 10
console.log(ptr2.value); // 10

ptr1.value = 20;
console.log(ptr1.value); // 20
console.log(ptr2.value); // 20

以上這個範例,我們先建立一個物件,接著,在用變數ptr1指向此物件,
接著,透過ptr2 = ptr1,將ptr2指向ptr1的位置。
像這種透過引用的方式傳遞資料,接收的是引用的「參考」而不是值得副本,
所以,當我們透過變數ptr1或ptr2來更改value屬性,皆會影響這個value的值。
此種狀況,我們稱之為「傳址」。

「傳值」還是「傳址」? (Pass by sharing)

書中介紹了基礎型別「傳值」 和 物件型別「傳址」 的例外狀況。
ex1:

1
2
3
4
5
6
7
var ptr = {value:10};
function changeValue(obj){
obj = {value:20};
}

changeValue(ptr);
console.log(ptr.value); // 10

可以看到ptr物件的value值,經過changeValue函式後,並沒有被更改。
以上這個例子,就是物件型別不是傳址的例子,以上這種狀況就是稱「Pass by sharing」。

「Pass by sharing」的特點就在於,當function的參數被重新賦值時,
外部變數的內容是不會被影響的。

若不是重新賦值的話,就會回到原本的狀況
ex2:

1
2
3
4
5
6
7
var ptr = {value:10};
function changeValue(obj){
obj.value = 20;
}

changeValue(ptr);
console.log(ptr.value); // 20,此時,ptr的value變成20

以上這兩個例子,可看出在物件型別的狀況下,當我們重新賦值的時候,會產生一個新的實體參考,
也就是第一個例子的狀況。
而當你只有更新物件的某些部分的時候,就會影響到所有引用該物件的變數與其副本,
也就是第二個範例。