JavaScript中的函數參數傳遞


JavaScript中所有函數的參數都是按值傳遞的。這是紅寶書裏對於函數參數傳遞的描述。很簡練。但有時候因爲大意,常常會因此犯一些錯誤。


問題描述:

最近在開發室內定位的過程中,由於需要保存一組座標數據,然後當做參數傳遞,並修改參數的內容展現在地圖上,最後再把保存的座標數據重新當做參數傳遞。由於疏忽,導致了一系列的問題。然後引發了對JS中基本數據類型,和引用類型的定義及其複製和參數傳遞的一些思考。



首先 我們先來介紹下JavaScript中的數據類型

在JavaScript中數據類型可以分爲兩類:

基本類型值:

比如Undefined,Null,Boolean,Number,String。

引用類型值:

比如Object,Array,Function,Date等。

基本類型值,存儲在棧中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置。這是因爲這些原始類型佔據的空間是固定的,所以可將他們存儲在較小的內存區域 – 棧中。這樣存儲便於迅速查尋變量的值。

引用類型值,存儲在堆中的對象,也就是說,存儲在變量處的值是一個指針,指向存儲對象的內存地址。這是因爲:引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。地址的大小是固定的,所以把它存儲在棧中對變量性能無任何負面影響。


由於不同的內存分配機制,也就產生了不同的訪問機制。在JavaScript中是不允許直接訪問保存在堆內存中的對象的,所以在訪問一個對象時,首先得到的是這個對象在堆內存中的指針,然後再按照這個指針去獲得這個對象中的值,這就是按引用訪問。而原始類型的值則是可以直接訪問到的。

而兩種數據類型在複製時,也產生不同的差異。基本類型值,在將一個保存着原始值的變量複製給另一個變量時,會將原始值的副本賦值給新變量,此後這兩個變量是完全獨立的,他們只是擁有相同的值而已。而引用類型值,在將一個保存着對象內存地址的變量複製給另一個變量時,會把這個內存地址賦值給新變量,也就是說這兩個變量都指向了堆內存中的同一個對象,他們中任何一個作出的改變都會反映在另一個身上。這是因爲複製對象時並不會在堆上新創建一個相同的對象,只會創建一個保存了指向這個對象的指針變量。


看下面例子


所以,現在再回到我們開頭的那句話。JavaScript中所有函數的參數都是按值傳遞的,也就是說把函數外部的值複製給函數內部的參數。基本類型值,只是把變量裏的值傳遞給參數,之後參數和這個變量互不影響。而引用類型值,則是對象變量裏面的值是這個對象在堆內存中的內存地址。這個指針指向了原始對象,對參數的任何操作都會反應到原始對象上。


同樣,看下面例子



我們應該時刻記住基本類型和引用類型之間的差異。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章