js函數傳參

來源:互聯網
上載者:User

標籤:alt   不同   存在   ret   count   arguments   href   png   object   

 也許大家對於函數的參數都不會太在意,簡單來說,把函數外部的值複製給函數內部的參數,就和把值從一個變數複製到另一個變數一樣。深入研究,你會發現其實沒那麼簡單,這個傳參是要分倆種情況(其實這是個錯誤的說法,ECMAScript中所有函數的參數都是按值傳遞的——《高程3》原話,之所以這裡說倆種,是因為結合引用傳參更容易理解)—— 值傳參和引用傳參。 

  值傳參針對基本類型,引用傳參針對參考型別,傳參可以理解為複製變數值。基本類型複製後倆個變數完全獨立,之後任何一方改變都不會影響另一方;參考型別複製的是引用(即指標),之後的任何一方改變都會映射到另一方。

  不少人對參數都是按值傳遞的感到困惑,因為訪問變數有按值和按引用兩種方式。下面就來看看有何不同:

  

  這一段很重要:我們可以把ECMAScript函數的參數想象成局部變數。在向參數傳遞基本類型的值時,被傳遞的值被複製給一個局部變數(即具名引數,或者用ECMAScript的概念來說,就是arguments對象中的一個元素)。在向參數傳遞參考型別時,會把這個值在記憶體中的地址(指標)複製給一個局部變數,因此這個局部變數的變化會反映在函數的外部。

 

  1、按值傳遞

1 function addTen(num) {2     num += 10;3     return num;4 }5 6 var count = 20;7 var result = addTen(count);  //按值傳遞 num = count8 alert(count);  // 20, 沒變化9 alert(result);  // 30

  很好理解,因為是按值傳遞的,傳遞完後倆個變數各不相干!

 

  2、按引用傳遞(這麼叫便於理解,其實也是按值傳遞)

1 function setName(obj) {2     obj.name = "Nicholas";3 }4 5 var person = new Object();6 setName(person);   //相當於按值傳遞  obj = person7 alert(person.name);   // "Nicholas"

   var person = new Object(); 時,可以用表示變數和對象的關係:

  當調用函數 setName(person); 時,可以表示全域變數person和局部變數obj的關心:

  以上代碼中建立一個對象,並將其儲存在變數person中。然後,這個變數被傳遞到setName(obj)函數中之後就被複製給了obj。在這個函數內部,obj和person引用的是同一個對象。換句話說,即使ECMAScript說這個變數時按值傳遞的,但obj也會按引用來訪問同一個對象。於是,在函數內部為obj添加name屬性後,函數外部的person也將有所反應;因為這時的person和obj指向同一個堆記憶體位址。所以,很多人錯誤的認為:在局部範圍中修改的對象會在全域對象中反映出來,就說明參數是按引用傳遞的。

  

  為了證明對象也是按值傳遞的,我們再來看看下面這個經過修改的例子:

1 function setName(obj) {2     obj.name = "Nicholas";3     obj = new Object(); //改變obj的指向,此時obj指向一個新的記憶體位址,不再和person指向同一個4     obj.name = "Greg";5 }6 7 var person = new Object();8 setName(person);  //你看看下面,相信我也是按值傳遞的了吧9 alert(person.name);  //"Nicholas"

  當建立obj對象 obj = new Object();  時,來看看這時person和obj的關係圖:

  這個例子與前一個唯一的區別,就是setName()函數中添加了兩行代碼: obj = new Object(); 用來改變obj的指向; obj.name = "Greg"; 用來給新建立的obj添加屬性。如果是按引用傳遞的,那麼person就會自動被修改為指向新建立的obj的記憶體位址,則person的name屬性值被修改為"Greg"。但是,當訪問person.name時,顯示的結果為"Nicholas"。這說明即使在函數內部修改了參數的值,但原始的引用仍然保持未變。實際上,當在函數內部重寫obj時,這個變數引用的就是一個局部對象了。而這個局部對象會在函數執行完畢後被立即銷毀!

雖然變數person和參數obj的值一樣都是同一個對象在記憶體中的地址,但它們是兩個相互獨立的變數。如果在函數中改變參數obj的值,使其指向記憶體中另外一個對象,變數person的值不會改變,還是指向原來的對象。

因此JavaScript中函數的參考型別值參數的傳遞是按值傳遞的。

 

js函數傳參

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.