今天要來探討一下傳址與傳值之間的差別,順便提及一下在JS還有另一個特性叫做pass by sharing
我們先看看以下例子
let a = 1
let b = 1
console.log(a === b) //true
let c = 'ck'
let d = 'ck'
console.log(c === d) //true
以上例子都為true應該不難理解吧!因為他們都指向同一個「值」
但我們再來看看如果指向的是物件的話會出現什麼
let a = { ck: 1 }
let b = { ck: 1 }
console.log(a === b) //false
上述印出的結果為會是false
!!!!!!
那是因為他們指向的雖然看起來是同一個物件,但其實這兩個物件並不是同一個物件,我們用更簡單的例子來理解!
假設我與你都有一個麥X勞的雙層牛肉吉士堡,我們都一樣是漢堡,但我的跟你的一定不是同一個實體對吧!今天我吃了一口不代表你的也被咬了一口。物件可以看做是一個實體,各自都不一樣,所以得出的結果才是false
。
那我們再來一個情況
let a = { ck: 1 }
let b = a
這時console.log(a === b)
會印出true
還是false
?
.
.
.
答案是true
這就像是我跟你現在跟你一起吃一個雙層牛肉吉士堡,所以答案才會是true
let a = 1
let b = a
console.log(a === b) //true
因為b
複製了a
的值所以他們是同一個沒錯但如果今天a
更新了之後b
的答案會是?
let a = 1
let b = a
a = 10
console.log(b) //1
這是因為b
一開始複製的是a
的值,當a
更新的時候並不會連同b
的值一起更新。這種就稱為「傳值」(pass by value)
let a = { ck: 1 }
let b = a
console.log(a === b) //true
同樣道理b
複製了a
的物件,所以現在他們指向同一個物件,那我們來試試看如果對a
做更新的話會發生什麼事
let a = { ck: 1 }
let b = a
a.ck = 2
console.log(a)
console.log(b)
我相信你們應該知道答案了吧XD 沒錯 b
的值也會被更新成ck: 2
也就是說今天a === b
會是true
,a
被更新後,連帶b
也被更新是因為他們指向的是同一個物件實體!才會導致連帶被更新,這種我們稱為「傳址」(pass by address)
如果已經能夠理解傳值以及傳址的差別之後,我們來看看JS裡還有一個特殊的情況稱為「Pass by sharing」
我們舉個例子
var a = { ck: 1 }
function b(x) {
return x = { ck: 2 }
}
console.log( b(a) ) // { ck: 2 }
console.log(a) // { ck: 1 }
能夠看到雖然在函式內我們已經將a
重新賦值,但並不會影響到原本外面的a
,但如果不是重新賦值的話
var a = { ck: 1 }
function b(x) {
return x.ck= 2
}
console.log( b(a) ) // 2
console.log(a) // { ck: 2 }
這邊只有更新的緣故所以外面的a
同時也被更新值了!
今天大概講解到這邊,大家明天見!