在傳統的觀念里,都認為JavaScript函數傳遞的是引用傳遞(也稱之為指針傳遞),也有人認為是值傳遞和引用傳遞都具備。那么JS的參數傳遞到底是怎么回事呢?事實上以下的演示也完全可以用于Java
首先來一個比較簡單的,基本類型的傳遞:
function add(num){ num+=10; return num;}num=10;alert(add(num));aelrt(num);//輸出20,10對于這里的輸出20,10,按照JS的官方解釋就是在基本類型參數傳遞的時候,做了一件復制棧幀的拷貝動作,這樣外部聲明的變量num和函數參數的num,擁有完全相同的值,但擁有完全不同的參數地址,兩者誰都不認識誰,在函數調用返回的時候彈出函數參數num棧幀。所以改變函數參數num,對原有的外部變量沒有一點影響。
再來看一個較復雜的,對象引用類型的傳遞:
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對象的值
那么可能有的朋友可能會問,這樣也可以理解為一個引用傳遞(指針傳遞)呀?不,這里嚴格的說,在和JAVA類似的語言中,已經沒有了指針,在JAVA里將上述過程稱之為一個從符號引用到直接引用的解析過程。在C里面,指針就是一個具有固定長度的類型(在大多數的C編譯器里是2個字節),但在JAVA類似的語言里,引用也有自己的屬性和方法,只是你不能直接去訪問和控制它,所以它從某種意義上也是一種對象,這種機制也很大程度的避免了內存泄露,術語稱之為內存結構化訪問機制。
為了證明上述觀點,稍微改造下上述例子:
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參數,有著完全不同的值和內存地址。
以上這篇淺談JavaScript 函數參數傳遞到底是值傳遞還是引用傳遞就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持武林網。
新聞熱點
疑難解答