js-- 堆棧內存關係

一、棧(stack)堆(heap)數組

  stack爲自動分配的內存空間,它由系統自動釋放;函數

  而heap則是動態分配的內存,大小不定也不會自動釋放。編碼

二、基本類型和引用類型spa

  基本類型:存放在棧內存中的簡單數據段,數據大小肯定,內存空間大小能夠分配。3d

  5種基本數據類型有Undefined、Null、Boolean、Number 和 String,它們是直接按值存放的,因此能夠直接訪問。指針

  引用類型:存放在堆內存中的對象,變量實際保存的是一個指針,這個指針指向另外一個位置。每一個空間大小不同,要根據狀況開進行特定的分配。code

  當咱們須要訪問引用類型(如對象,數組,函數等)的值時,首先從棧中得到該對象的地址指針,而後再從堆內存中取得所需的數據。對象

三、傳值與傳址blog

    var a = [1,2,3,4,5];
    var b = a;
    var c = a[0];
    alert(b);//1,2,3,4,5
    alert(c);//1
    //改變數值        
    b[4] = 6;
    c = 7;
    alert(a[4]);//6
    alert(a[0]);//1

a-b:傳址   a-c:傳值遞歸

  

三、淺拷貝

  前面已經提到,在定義一個對象或數組時,變量存放的每每只是一個地址。當咱們使用對象拷貝時,若是屬性是對象或數組時,這時候咱們傳遞的也只是一個地址。所以子對象在訪問該屬性時,會根據地址回溯到父對象指向的堆內存中,即父子對象發生了關聯,二者的屬性值會指向同一內存空間。

 

   let a = {
      key1: 111
    }
    function shallowCopy(p){
      let c = {}
      for(let i in p){
        c[i] = p[i]
      }

      return c
    }
  
    a.key2 = ['a','b']
    let b = shallowCopy(a)
    b.key3 = 333

    console.log('a', a)
    /** a:key1:111
          key2:['a','b']
          */
    console.log('b', b)
    /** b:key1:111
          key2:['a','b']
          key3:333
        */ 

    /**淺拷貝: 爲b添加新屬性,並未影響到a*/

    /**修改一下a的數組*/
    b.key2.push('c')

    console.log('a.key2',a.key2)
    /**
      a.key2:['a','b','c']
  a中key2也發生了改變
*/

 

緣由是key1的值屬於基本類型,因此拷貝的時候傳遞的就是該數據段;可是key2的值是堆內存中的對象,因此key2在拷貝的時候傳遞的是指向key2對象的地址,不管複製多少個key2,其值始終是指向父對象的key2對象的內存空間。

四、深拷貝

或許以上並非咱們在實際編碼中想要的結果,咱們不但願父子對象之間產生關聯,那麼這時候能夠用到深拷貝。既然屬性值類型是數組和或對象時只會傳址,那麼咱們就用遞歸來解決這個問題,把父對象中全部屬於對象的屬性類型都遍歷賦給子對象便可。

 
 
let a = {
      key1: 111 }
a.key2 = ['a','b']
function deepCopy(p,c){
      let c2 = c ||{};
      for(let i in p ){
        if(typeof p[i] === 'object'){
          c2[i] = (p[i].constructor === Array) ? [] : {}
          deepCopy(p[i],c2[i])
        }else{
          c2[i] = p[i]
        }
      }
      return c2
    }
    let d = {}
    d = deepCopy(a , d)
    d.key2.push('d')

    console.log('a.key2',a.key2) //a.key2: ["a", "b", "c"]
    console.log('d.key2',d.key2) //d.key2: ["a", "b", "c", "d"]
/**新生成的子對象並無影響父對象*/
 

 

相關文章
相關標籤/搜索