我們把命名參數(arguments)視為局部變數,在向參數傳遞基本類型值時,如同基本類型變數的複製一樣,傳遞一個副本,參數在函數內部的改變不會影響外部的基本類型值。如: 在向參數傳遞引用類型的值時,會把這個值 在記憶體中的地址複製給一個局部變數,因此這個局部變數的變化會反映子啊函數的外部,例如: 這個 ...
我們把命名參數(arguments)視為局部變數,在向參數傳遞基本類型值時,如同基本類型變數的複製一樣,傳遞一個副本,參數在函數內部的改變不會影響外部的基本類型值。如:
1 function add10(num){ 2 num += 10 ; 3 return num ; 4 } 5 var count = 10 ; 6 var result = add10(count); 7 alert(count);// 10 8 alert(result); //20
在向參數傳遞引用類型的值時,會把這個值 在記憶體中的地址複製給一個局部變數,因此這個局部變數的變化會反映子啊函數的外部,例如:
function addName(obj){
obj.name = "Jewl";
}
var someBody = new object();
addName(someBody);
console.log(someBody.name); //"Jewl"
這個例子其實是很讓人困擾的,因為它更像按引用傳遞,說到傳遞方式,一般分為兩種:
1.按值傳遞(call by value):函數的形參是被調用時所傳實參的副本。修改形參的值並不會影響實參。
2.按引用傳遞(call by reference):函數的形參接收實參的隱式引用,而不再是副本。這意味著函數形參的值如果被修改,實參也會被修改。同時兩者指向相同的值。
為了證明引用類型也是按值傳遞的,我們可以看看下麵一個例子:
function addName(obj){
obj.name = "Jewl';
obj = new object();
obj.name = "Kancy";
}
var someBody = new object();
addName(someBody);
console.log(someBody.name) //"Jewl"
與前面一個例子的區別是,本例將一個新對象賦值給形參,如果是按引用傳遞,那麼someBody的name也會隨之改變,顯然不是。在函數內部給obj賦值時,這個變數引用就變成了一個局部變數,在函數執行完就會被銷毀。
為了加深理解,我會再來看看js中引用類型值的存儲,在js中,引用類型值是保存在記憶體中的對象,JavaScript不允許直接訪問記憶體中的位置,也即不能直接操作對象的記憶體空間,在操作對象時,實際上是操作對象的引用而不是實際的對象。引用類型的值是按引用訪問的。因此改變其中一個變數,就會影響另外一個變數。
var obj1 = new Object();
var obj3 = new Object();
var obj2 = obj1;
obj1.name = "Jewl";
obj3.name = "Kancy";
console.log(obj1.name); //"Jewl"
console.log(obj2.name); //"Jewl"
obj1 = obj3;
console.log(obj1.name); //"Kancy"
console.log(obj2.name); //"jewl"
console.log(obj3.name); //"kancy"
當我們把obj1賦值為obj3時,obj1指向和obj3相同的對象,obj2依然指向之前的對象。由此可以看出傳參過程和此處類似,但不屬於按引用傳參,所以講JavaScript里參數傳遞均歸為按值傳遞。
JavaScript新手,第一次發文,請多指教。