談談 js 深淺拷貝 那點事(一)

找抽的小陀螺發表於2017-10-12

深拷貝與淺拷貝 不知道大家是咋理解的 有沒有從記憶體空間角度去理解 前天看了一個記憶體空間 堆疊 下面賣弄下

在學習資料結構時候 堆疊是很熟悉了 在一端去對資料的操作

簡單說 棧為自動分配記憶體空間 由系統自動釋放
堆是動態分配的記憶體 大小不定也不會自動釋放

  • 棧資料結構
    網上好的例子

上圖很詳細的說明了棧資料結構空間的儲存
對於棧來說 棧的資料操作 都要在棧頂來操作

  • 堆資料結構

上面可以看到都是散落的
對於堆來說 資料項沒有固定順序 不想棧一樣有順序 在堆運算元據可以任何順序操作 不需要必須在頂部來操作

  • js 資料型別 和堆 棧
    js中資料型別分為兩類

    1. 基本型別: Undefined Null Boolean Numer String 5種基本資料型別放在棧記憶體中簡單資料段 資料大小確定 記憶體空間自動分配

      var name = 'jozo'
      var city = 'gaungzhou'
      var age = 22複製程式碼

      上面有幾個基本型別變數 在記憶體中結構
      記憶體中 包括了變數的 標識 和 值

  1. 引用型別: Object Array fun 這些引用型別 比如陣列 他們的值大小是不固定的 這些放在堆記憶體中 js是不允許直接訪問堆記憶體因此不能直接操作物件堆記憶體空間 在變數中實際上儲存一個指標 這個指標指向另一個位置 實際要操作的是一個指標 不是實際物件 這個地址跟堆記憶體的實際值相關聯

       var a = 20
       var b = 'abc'
       var c = true
       var d = { m:20 }複製程式碼


上圖可以看到 當要訪問對記憶體中引用型別時候 實際上從變數物件中獲取這個物件地址指標 然後從堆記憶體中獲取資料

上面js中的資料型別記憶體儲存

  • 資料型別特性

    1. 看基本資料型別

      var a = 1
      var b = a
      b = 2   //a還是1複製程式碼

      基本資料型別儲存在棧中 系統自動為變數分配一個值 a b 都是1 但是他們是棧中兩個相互對立的東西 所以修改b 對於a來說沒有影響

    2. 看引用資料型別

      var m = { a: 10, b: 20 }
      var n = m
      n.a = 15複製程式碼

      引用型別真正的物件儲存在堆中 var m = {} 在棧中儲存了一個標識跟值 根據上述說的引用型別棧中變數物件儲存是一個 堆記憶體的指標地址
      var n = m 這裡棧中自動為其分配一個空間 也是儲存一個標識跟值 值也是儲存的一個指標地址
      n.a = 15 改變了n的a屬性 雖然棧中儲存的兩個相互獨立東西 但是指標指向堆記憶體是物件是一樣的 就導致了 m 也改變了

可以看到如果通過這種方式來看的話 引用型別 基本型別本質上的區別 按值 按址
下一篇拷貝實際例子
參考連結:
記憶體空間詳細圖解

相關文章