綜合本系列此前的彙整,構成JavaScript資料的基本型別(primitives)是指字串、數字、布林值、null、undefined等「純值」;而物件型別(object)則是**複數的「純值」或「物件」**所組成。
在基本型別中,判定兩個變數是否相等,就是看他的「值」。以數字為例:
var yearMinguo = 1
var yearTaisho = 1
console.log(yearMinguo === yearTaisho); //得出true,字面舉例是:民國元年也是大正元年
在物件型別中,即使兩個變數可能「等值」,但不同的物件就是不同的實體(instance),直接比較不會相等。比如:
var Taiwan = { value: "Takao" };
var Kyoto = { value: "Takao" };
console.log(Taiwan === Kyoto); //得出false,字面舉例是:台灣與京都都有一個高雄(Takao),但不等於台灣是京都
如前所述,當我們比較兩個基本型別時,是比較其「值」。因此複製、傳遞時,也只涉及「值」。
當我們們複製變數時,若「值」相同,尚看不出差異:
var yearMinguo = 15
var yearTaisho = yearMinguo
console.log(yearMinguo); //得出15,基於值
console.log(yearTaisho); //得出15,基於yearMinguo的值
但「被引用的變數」變更值之後,引用者的值並不會同步更新:
var yearMinguo = 110
console.log(yearMinguo); //得出110,基於值
console.log(yearTaisho); //得出15,字面舉例是:民國110年了,大正仍是15年
這種變數間引用後「值」彼此獨立的情形,即為傳值(pass by value)。
在物件型別中,若一樣作變數引用,「值」相同也看不出差異:
var Taiwan = { value: "Takao" };
var Kyoto = Taiwan;
console.log(Taiwan); //得出Takao
console.log(Kyoto); //得出Takao
但「被引用的變數」變更值之後,引用者也會一起更新:
var Taiwan = { value: "Kaohsiung" };
console.log(Taiwan); //得出Kaohsiung
console.log(Kyoto); //得出Kaohsiung
因為此時Taiwan、Kyoto兩個變數已經成為同一個實體(內台一體了XD)
console.log(Taiwan === Kyoto); //得出true
這種變數間指向「同一實體」的情形,即為傳址(pass by reference)。
筆者的小口訣:總之「物件會跟著變」。
確實掌握JavaScript「傳值」或「傳址」的實情,對構築程式至關重要。惟若「函式中的參數」被「重新賦值」的話,就不受外部變數「傳址」規則的影響了。