前言
這個章節要來介紹 傳值 (Value) vs. 傳參考 (Reference)
首先我們先來看看程式碼
var person = 'Bob';
var person2 = person;
person2 = 'May';
console.log(person, person2); // Bob , May
上面這段程式碼先建立了 person 這個變數,並且賦值字串的'Bob'給他,之後也建立了 person2 的變數,
並且將 person 這個變數的內容指向給 person2 的變數。這時候 person2 的變數 的值會是 'Bob' ,
之後再將 person2 的變數重新賦值給一個字串 'May',所以最後印出來的結果會是 Bob May 很合理 ~
那我們再來看看另一段程式碼
var person = {
name: 'Bob'
};
var person2 = person;
person2.name = 'May';
console.log(person.name, person2.name); // May , May
console.log(person === person2); // true
兩個都是 May,而且用嚴格比對兩個物件居然還是 true ,怎麼會這樣呢?
其實這也是 Javascript 的特性
物件傳參考的特性
Javascript 在賦予一個值在變數上的時候,會有兩個特性,一個稱為 傳值 另一個則是 傳參考
如上圖,左邊類型的資料型別就是傳值,也就是最上方字串的範例,做修改的時候只會更動被修改的變數內容。
而只要是物件型別的資料結構,就是屬於傳參考的模式,傳的參考其實是記憶體位置
傳值
以這個範例來看
var person = '小明';
var person2 = person;
person2 = '杰倫';
console.log(person, person2); // 小明 , 杰倫
當 var person2 = person; 的時候,就會變成下圖的狀況
接著我們改變了 person2 的內容,但因為是傳值,所以 person 並不會跟著改變
傳參考
接下來看一下 傳參考 的概念
圖片中的 0x01 代表物件的內容被宣告的記憶體位置
可以看到當我們宣告 var person2 = person; 的時候,其實是將 person 的記憶體位置也指向給 person2,也就是 person 以及 person2 都共享同一個記憶體空間的內容,也就是 0x01 的 物件內容。
所以依照這個邏輯來看,當我們改變了不論是 person 還是 person2 的 name,兩者取值印出來的結果都會一樣,是被改變後的結果。
那麼如果今天重新賦予 perosn2 新的 物件實字 的物件的話呢,他就會重新再另一個記憶體空間,放置被賦予的物件
這樣子更改 name 的值,就不會造成兩個一起更動的狀況囉 ~
那我們直接看看程式碼
var person = {
name: '小明'
};
var person2 = person;
person2 = {
name: '小明'
};
console.log(person.name, person2.name); // 小明 , 小明
console.log(person === person2); // false
可以看到,重新以一個物件實字的方式重新賦予給 person2 一個跟 person 一模一樣結構跟內容的物件。但對於記憶體空間來說,這樣賦值的方式就會是指向另一個記憶體空間,所以在嚴格比對的結果才會是false
從這點來看,關於 Javascript 物件類型的資料型別,以嚴格模式比對的時候,其實比對的是 記憶體位置 !!