JavaScript-傳值與傳參考

傳值(by value)

首先宣告一個變數a,並且assign一個純值(primitive)給a,則在記憶體中會有以個0x001位置存有該值,等著被a參照。
接著,宣告一個變數b,並且將a指派給b (b = a),實際上的執行狀況,會將a參照到的記憶體位置中的值複製到一個新的記憶體位置0x002,再讓b可以參照到它。

以下方程式碼為例,當執行到第6行,若重新assign一個值給a,並不會影響到b的值,因為a跟b是指向不同的記憶體位置,兩者的值不會互相被影響。

1
2
3
4
5
6
7
8
9
//call by value(primitives)
var a = 3;
var b;

b = a;
a = 2;

console.log(a);//2
console.log(b);//3

傳參考(by reference)

首先有一個變數a,將一個物件(包含函式)指派給該變數,則在記憶體中會有一個位置0x001存有該物件,並透過記憶體位置被a參照到。
接著,宣告一個變數b,並且將a指派給b (b = a),此時並不會得到一個新的物件以及新的記憶體位置,而是會讓b也參照到跟a同個物件所在記憶體中的位置,也就是同樣指向0x001。
這也代表,如果a的值被改變,b的值也同樣會被改變,因為它們兩者指向的物件就是同一個物件。

以下方程式碼為例,當執行到第6行,執行mutate,改變a物件中的值,接著再分別印出a、b的值,會發現兩者的結果皆被改變為mutate後的值了。

1
2
3
4
5
6
7
8
9
// call by reference(all objects, including functions)
var a = { greeting:'hi'};
var b;

b = a;
a.greeting = 'hello';

console.log(a);//{ greeting:'hello'}
console.log(b);//{ greeting:'hello'}

傳參考(用於參數)

在第5行,b已經指向a同個物件的記憶體,而當第9行將b作為傳入參數作為函式中obj物件,在第7行被mutate之後,最終a跟b所印出的值皆相同,因為兩者皆是指向同個記憶體位置中的同個物件。

1
2
3
4
5
6
7
8
9
10
11
12
//call by reference (even as parameters)
var a ={ greeting:'hi'};
var b;

b = a;
function changeGreeting(obj){
obj.greeting = 'hola';
}
changeGreeting(b);

console.log(a);//{ greeting:'hola'}
console.log(b);//{ greeting:'hola'}

使用等號運算子,創建一個新的記憶體空間

透過”=”運算子創建物件,藉由這個物件實體語法,因為不知道{ greeting:'hola'}是否已經存在於記憶體,所以會另外創建一個記憶體空間給新的物件。

1
2
3
4
5
6
7
8
9
//equals operator sets up a new memory space(new address)
var a = { greeting:'hi'};
var b = a;

a.greting = 'hello';
a = { greeting:'hola'};

console.log(a);//{ greeting:'hola'}
console.log(b);//{ greeting:'hello'}

© 2020 Leah's Blog All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero