js函數傳遞對象參數

1、在 javascript 中數據類型能夠分爲兩類:javascript

  • 原始數據類型值 primitive type,如Undefined,Null,Boolean,Number,String。
  • 引用類型值,也就是對象類型 Object type,如Object,Array,Function,Date等。

2、聲明變量時不一樣的內存分配java

  • 原始值:存儲在棧(stack)中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置。這是由於這些原始類型佔據的空間是固定的,因此可將他們存儲在較小的內存區域 – 「」中。這樣存儲便於迅速查尋變量的值
  • 引用值:存儲在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(point),指向存儲對象的內存地址。這是由於:引用值的大小會改變,因此不能把它放在棧中,不然會下降變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。地址的大小是固定的,因此把它存儲在棧中對變量性能無任何負面影響。

image.png

3、不一樣的內存分配機制也帶來了不一樣的訪問機制函數

在javascript中是不容許直接訪問保存在「堆」內存中的對象的,因此在訪問一個對象時,首先獲得的是這個對象在堆內存中的地址,而後再按照這個地址去得到這個對象中的值,這就是傳說中的按引用訪問。而原始類型的值則是能夠直接訪問到的。性能

一、複製變量時的不一樣spa

  • 原始值:在將一個保存着原始值的變量複製給另外一個變量時,會將原始值的副本賦值給新變量,此後這兩個變量是徹底獨立的,他們只是擁有相同的value而已。
  • 引用值:在將一個保存着對象內存地址的變量複製給另外一個變量時,會把這個內存地址賦值給新變量,也就是說這兩個變量都指向了堆內存中的同一個對象,他們中任何一個做出的改變都會反映在另外一個身上。(這裏要理解的一點就是,複製對象時並不會在堆內存中新生成一個如出一轍的對象,只是多了一個保存指向這個對象指針的變量罷了)

image.png

2.參數傳遞的不一樣指針

首先咱們應該明確一點:ECMAScript中全部函數的參數都是按值來傳遞的。可是爲何涉及到原始類型與引用類型的值時仍然有區別呢,還不就是由於內存分配時的差異。 (這個複製變量時遵循的機制徹底同樣)code

  • 原始值:只是把變量裏的值傳遞給參數,以後參數和這個變量互不影響。
  • 引用值:對象變量它裏面的值是這個對象在堆內存中的內存地址,這一點你要時刻銘記在心!所以它傳遞的值也就是這個內存地址,這也就是爲何函數內部對這個參數的修改會體如今外部的緣由了,由於它們都指向同一個對象呀。圖示說明:

因此,若是是按引用傳遞的話,是把第二格中的內容(也就是變量自己)整個傳遞進去(就不會有第四格的存在了)。但事實是變量把它裏面的值傳遞(複製)給了參數,讓這個參數也指向原對象。所以若是在函數內部給這個參數賦值另外一個對象時,這個參數就會更改它的值爲新對象的內存地址指向新的對象,但此時原來的變量仍然指向原來的對象,這時候他們是相互獨立的;但若是這個參數是改變對象內部的屬性的話,這個改變會體如今外部,由於他們共同指向的這個對象被修改了呀!來看下面這個例子吧:(傳說中的call by sharing)對象

var obj1 = { value:'花點時間1' }; 
var obj2 = { value:'花點時間2' }; 
function changeStuff(obj){ 
    obj.value = '花點時間3'; 
    obj = obj2; 
    return obj.value; 
} 
var foo = changeStuff(obj1); 
console.log(foo);// '花點時間2' 參數obj指向了新的對象obj2 
console.log(obj1.value);//'花點時間3',形參obj和對象obj1指向了共同的內存地址,obj改變後,堆(heap)內存中的對象改變,所以obj1的值也發生了改變。
相關文章
相關標籤/搜索