JavaScript 函數參數傳遞究竟是值傳遞仍是引用傳遞

    tips:這篇文章是聽了四腳貓的js課程後查的,深刻的理解能夠參看兩篇博客:html

  JavaScript數據類型--值類型和引用類型函數

  JavaScript數據操做--原始值和引用值的操做本質post

    在傳統的觀念裏,都認爲JavaScript函數傳遞的是引用傳遞(也稱之爲指針傳遞),也有人認爲是值傳遞和引用傳遞都具有。那麼JS的參數傳遞究竟是怎麼回事呢?事實上如下的演示也徹底能夠用於Javaspa

    首先來一個比較簡單的,基本類型的傳遞:指針

function add(num){ num+=10; return num; } num=10; alert(add(num)); aelrt(num); //輸出20,10

  對於這裏的輸出20,10,按照JS的官方解釋就是在基本類型參數傳遞的時候,作了一件複製棧幀的拷貝動做,這樣外部聲明的變量num和函數參數的num,擁有徹底相同的值,但擁有徹底不一樣的參數地址,二者誰都不認識誰,在函數調用返回的時候彈出函數參數num棧幀。因此改變函數參數num,對原有的外部變量沒有一點影響。code

    再來看一個較複雜的,對象引用類型的傳遞:htm

function setName(obj){ obj.name="ted"; } var obj=new Object(); setName(obj); alert(obj.name); //輸出ted

     以上代碼的運行的實質是:建立了一個object對象,將其引用賦給obj(在C裏面就直接是一個內存地址的賦值),而後在傳遞函數參數的時候,作了一件與前一個方法相同的事情,複製了一個棧幀給函數參數的obj,二者擁有相同的值(不妨將其理解爲object對象的地址),而後在setName作改變的時候,事實上是改變了object對象自身的值(在JAVA裏稱之爲可變類),在改變完成以後一樣也要彈出函數參數obj對應的棧幀。對象

      因此對應的輸出是改變後object對象的值blog

     那麼可能有的朋友可能會問,這樣也能夠理解爲一個引用傳遞(指針傳遞)呀?不,這裏嚴格的說,在和JAVA相似的語言中,已經沒有了指針,在JAVA裏將上述過程稱之爲一個從符號引用到直接引用的解析過程。在C裏面,指針就是一個具備固定長度的類型(在大多數的C編譯器裏是2個字節),但在JAVA相似的語言裏,引用也有本身的屬性和方法,只是你不能直接去訪問和控制它,因此它從某種意義上也是一種對象,這種機制也很大程度的避免了內存泄露,術語稱之爲內存結構化訪問機制。ip

    爲了證實上述觀點,稍微改造下上述例子:

 

function setName(obj){ obj.name="ted"; obj=new Object(); obj.name="marry"; } var obj=new Object(); setName(obj); alert(obj.name); //輸出ted

  這個例子與上一個例子的惟一不一樣是這裏將一個新的對象賦給了函數參數obj,這樣函數參數obj和原有的引用obj參數,有着徹底不一樣的值和內存地址。

相關文章
相關標籤/搜索