JavaScript變量存儲淺析(二)


Hello,上一篇(http://www.cnblogs.com/souvenir/p/4969399.html)我們簡單的分享了JS中的變量存儲原理,但是並未結束,我們漏掉了什么。

對了,就是關於對象的存儲。

 

  大家都知道,JavaScript中的變量類型分為兩種,一種是基本數據類型,包括:undefined,null,Number,String,Boolean,另外一種就是對象。

  兩種數據類型的存儲方式在JS中也有所不同。

  另外,內存分為棧區(stack)和堆區(heap),然后在JS中開發人員並不能直接操作堆區,堆區數據由JS引擎操作完成,那這二者在存儲數據上到底有什么區別呢?

  我們簡單的通過下面這張圖來分析:

  

  JS中變量的定義在內存中包括三個部分:

    •   變量標示  (比如上圖中的Str,變量標示存儲在內存的棧區)
    •   變量值     (比如上面中的Str的值souvenir或者是obj1對象的指向堆區地址,這個值也是存儲在棧區)
    •       對象        (比如上圖中的對象1或者對象2,對象存儲在堆區)

  也就是說,對於基本數據類型來說,只使用了內存的棧區。

 

  對於上一篇中提到的問題來說,

1 var a = 100;     
2  
3 func();
4 
5 function func(){
6     console.log(a);
7     var a=200;        
8     console.log(a);
9 }

  在JS預加載階段,JS引擎只是在內存的棧區為每個變量分配了內存,指定了標示符,並未為其指定值。

  等到JS執行期才會為其賦值。

 

  現在我們再來看對象變量的問題就比較清楚了,例如下面的:

 1 var a=100;
 2 var obj1={
 3     attr:'hello'
 4 };
 5 
 6 func(a,obj1);
 7 
 8 function func(num,obj){
 9     var a2=num;
10     a2=200;
11     
12     var obj2=obj;
13     obj2.attr='hello';
14 }
15 
16 console.log(a);
17 console.log(obj1.attr);

  我們分別定義了一個基本類型和對象類型的變量,然后在函數中對其分別執行復制操作,然后修改新變量的值。

  最后的執行結果為:

  

  對於基本數據類型,在執行第9行時,JS是把num在棧區的值,也就是100復制給了a2這個局部變量,然后在第10行又修改了a2的值,

  這個操作過程並未影響到全局變量a的值。

 

  小結:

  對於對象來說,當JS執行12行的時候,實際上是把obj在棧區的值,也就是obj對象在堆區的引用地址,復制給了新的局部變量obj2,

  這時候,obj2與obj實際上已經指向了同一個堆區的對象,然后obj2修改了這個對象的某個屬性值。然后函數執行完畢,obj2這個局部變量沒有引用將會被GC回收。

  再次訪問obj1這個全局變量時,其所指向的對象其實已經被修改過了。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM