#2.5 值傳遞和引用傳遞
藉助下面的例子,我們先來看一看什麼是值傳遞,什麼是引用傳遞:
let name = 'ConardLi';
function changeValue(name){
name = 'code祕密花園';
}
changeValue(name);
console.log(name);
執行上面的代碼,如果最終打印出來的name
是'ConardLi'
,沒有改變,說明函數參數傳遞的是變量的值,即值傳遞。如果最終打印的是'code祕密花園'
,函數內部的操作可以改變傳入的變量,那麼說明函數參數傳遞的是引用,即引用傳遞。
很明顯,上面的執行結果是'ConardLi'
,即函數參數僅僅是被傳入變量複製給了的一個局部變量,改變這個局部變量不會對外部變量產生影響。
let obj = {name:'ConardLi'};
function changeValue(obj){
obj.name = 'code祕密花園';
}
changeValue(obj);
console.log(obj.name); // code祕密花園
上面的代碼可能讓你產生疑惑,是不是參數是引用類型就是引用傳遞呢?
首先明確一點,ECMAScript
中所有的函數的參數都是按值傳遞的。
同樣的,當函數參數是引用類型時,我們同樣將參數複製了一個副本到局部變量,只不過複製的這個副本是指向堆內存中的地址而已,我們在函數內部對對象的屬性進行操作,實際上和外部變量指向堆內存中的值相同,但是這並不代表着引用傳遞,下面我們再按一個例子:
let obj = {};
function changeValue(obj){
obj.name = 'ConardLi';
obj = {name:'code祕密花園'};
}
changeValue(obj);
console.log(obj.name); // ConardLi
可見,函數參數傳遞的並不是變量的引用
,而是變量拷貝的副本,當變量是原始類型時,這個副本就是值本身,當變量是引用類型時,這個副本是指向堆內存的地址。所以,再次記住:
ECMAScript
中所有的函數的參數都是按值傳遞的。