按值傳遞、按引用傳遞、按共享傳遞
按值傳遞(call by value)
按值傳遞,就是指在調用函數時,將實參對應的值做一個拷貝指向函數對應的形參。在函數內改變形參對應的值并不會影響外部實參的值。
按引用傳遞 (call by reference)
按引用傳遞,是指在調用函數時,傳遞給函數的是實參的地址即引用,而不是實參的拷貝。在函數內部參數的值,對外部的實參是可見的。
按共享傳遞 (call by sharing)
按共享傳遞,是指在調用函數時,傳遞給函數的是實參的地址的拷貝(如果實參在棧中,則直接拷貝該值)。在函數內部對參數進行操作時,需要先拷貝的地址尋找到具體的值,再進行操作。如果該值在棧中,那么因為是直接拷貝的值,所以函數內部對參數進行操作不會對外部變量產生影響。如果原來拷貝的是原值在堆中的地址,那么需要先根據該地址找到堆中對應的位置,再進行操作。因為傳遞的是地址的拷貝所以函數內對值的操作對外部變量是可見的。
按共享傳遞可以理解為按值傳遞的一個特例,這里的值是對象的引用地址,而不是具體對象。
舉例
var a = 1
var b = 2
function change(x, y) {
var z = x
x = y
y = z
console.log('a = ' + x + ' , b = ' + y)
}
change(a, b)
console.log('a = ' + a + ' , b = ' + b)
//因為是傳值調用所以函數內部操作并未影響外部變量
var o1 = {name: 'Tom'}
function changeObj(o) {
o.name = 'Lucy'
console.log('name is : ' + o.name)
o = {name: 'Eve'}
console.log('name is : ' + o.name)
}
changeObj(o1)
console.log('name is: ' + o1.name)
//因為是按共享傳遞調用。所以如果是修改對象的值,對外部可見。但是當將形參的引用指向閑的對象時,由于該引用是一個原引用的拷貝,所以并未影響到原對象。