JS 函數參數及其傳遞


 

  函數的參數
一、函數的實參和形參
“JavaScript 中的函數定義並未指定函數形參的類型,函數調用也未對傳入的實參值做任何類型檢查,JavaScript 函數調用甚至不檢查傳入形參的個數 ”--摘自 JavaScript權威指南
二、可選形參
// 當調用函數的時候傳入的實參比函數聲明時指定的形參個數要少,剩下的形參都將設置為 undefined 值
1 function aFunc(a,b){ 2 console.log('a='+a,'b='+b) 3 } 4 aFunc("666"); // a = 666, b = undefined

三、可變長的實參列表:實參對象

// 當調用函數的時候傳入的實參個數超過函數定義時的形參個數時,沒有辦法直接獲取未命名的值的引用,參數對象解決了這個問題。
// 標志符:arguments 是指向實參對象的引用,它是一個類數組對象,可通過數字下標就能訪問傳入函數的實參的值。
1 function aFunc(param){ 2 console.log(param === arguments[0]); 3  console.log(arguments); 4 } 5 aFunc("strA","strB"); // true, Arguments(2) ["strA", "strB"]

從JS的變量復制看JS的參數傳遞

一,變量的復制:

 // 基本類型:從一個變量向另一變量復制基本類型的值,會在變量對象上創建一個新值,然后把該值復制到為新的變量分配的位置上 -> 獨立變量,互不影響
1
console.log(" 基本類型:"); 2 var num1=1; 3 var num2=num1; //此時num1=1,num2=1,這是兩個完全獨立的變量,互不影響,只是值相等而已 4 5 console.log(" before copy --> num1:"+num1+" , num2:"+num2); 6 //輸出 before copy --> num1:1 , num2:1 7 8 num1="change"; // 改變 num1 的值 9 10 console.log(" after copy --> num1:"+num1+" , num2:"+num2); 11 //輸出 after copy --> num1:change , num2:1
// 引用類型:從一個變量向另一變量復制引用類型的值,會在變量對象上,創建一個新值,然后把該值復制到為新的變量分配的位置上,不同的是,這個副本和原來的變量都是一個指針,指向堆內存中同一個對象
1
console.log(" 引用類型:"); 2 var obj1=new Object(); 3 var obj2=obj1; // 此時 obj1 和 obj2 是兩個獨立的引用,只是指向同一個地方而已 4 5 obj1.name="Guang Zai";// 改變 name 的值 6 7 console.log(" obj2.name:"+obj2.name); 8 //輸出: obj2.name:Guang Zai
9 //更改 obj1.name 的值,即更改 obj1 指向的那個地方的 name 屬性的值,obj2 也指向同一個地方,因此讀取 obj2 的 name 必然是更改后的結果
二,函數的參數傳遞:
 // 基本類型按值傳遞,傳進去的參數與外面的變量互相獨立,互不影響
1
function changeString(str){ 2 str+=": add something in the function" 3 return str; 4 } 5 6 console.log(" 基本類型:"); 7 var str="str"; 8 var str_return=changeString(str); 9 console.log(" str_return:"+str_return+" , str:"+str); 10 // 輸出:str_return:str: add something in the function , str:str
// 引用類型:在js中,所有函數的參數都是按照值傳遞的(按值傳遞 按值傳遞 按值傳遞 按值傳遞 按值傳遞 按值傳遞 按值傳遞 按值傳遞 按值傳遞 按值傳遞),
// 也就是說:把函數外部的值復制給函數內部的參數,就和把值從一個變量復制到另一個變量一樣,復制過程按照基本類型和引用類型對應的變量復制過程。
1 console.log(" 引用類型:");
2 function setName(obj){
3     obj.name="Guang Zai";
4     obj=new Object();
5     obj.name="guang";
6 }
7 var person=new Object();
8 setName(person);
9 console.log("   person.name:"+person.name);//輸出: "Guang Zai"

// 解析:函數外部創建一個對象person,然后調用setName函數傳遞參數
// 此時按照傳遞參數的過程,把person的值復制一份后傳遞給參數obj
// 使得obj的引用與person指向同一個對象
// 然后進入函數內部:
// obj.name="Guang Zai"; person.name也等於"Guang Zai" 因為此時 obj 的引用與 person 指向同一個對象
// obj=new Object(); 此時obj指向另一個對象,person依然指向原來的對象
// 因此obj之后的修改對person無影響,所以函數外部person.name="Gaung Zai"
// setName函數執行完成后,obj對象會被立即銷毀

 
 
 1 // 拓展分割線:----------------------------------------------------------------------
 2 // js中引用類型作為參數傳遞和java不一樣
 3 // java中引用類型作為參數傳遞時,傳遞的是該對象的引用
 4 // 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 傳遞的是引用 
 5 // 拿上面的例子來說,參數傳遞后應該是下面這樣:
 6 /*
 7  **********************other --------------------> {其他對象}
 8  ********obj,person {同一個引用,名字不一樣}) -----> 【對象】
 9  */
10 // 然后進入函數內部:
11 // obj.name="Guang Zai"; person.name也等於"Guang Zai"
12 // obj=new Object(); 此時obj指向另一個新的對象,person也指向那個新的對象
13 // 因為他們的引用是同意引用,因此對obj的修改就是對person的修改 
14 // setName函數執行完成后,obj對象和person的name屬性都是 “guang”,而不是原來的 ”Guang Zai“

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM