上篇 看到了從記憶體空間來看資料類在記憶體中存在情況 下面開始賣弄下js 深淺拷貝
淺拷貝
上篇瞭解到 基本型別拷貝 其實就是在棧中新開闢了一塊空間 原物件 跟拷貝出的物件是兩個互相獨立的東西
這也就是說基本型別深淺都是一樣的 深淺拷貝相對引用型別var a = { key1: '123', key2: [4,5] } console.log(a) //key1:123 key2: 陣列 function copy (a) { var obj = {} for (var i in a) { obj[i] = a[i] } return obj } var b = copy(a) //這裡棧記憶體中開闢了兩個空間 a b 這裡存放了物件的變數標識 跟 值(是引用型別就是指標) console.log(b.key1) // 123 這個a b 指標指向同一塊堆記憶體 key1 value值是123 b.key3 = '333' console.log(b.key3) //333 console.log(a.key3) //undefined 這個是key3是一個基本資料型別在 棧中b變數物件中值新增一個key3 並沒有通過指標 a b 相互獨立 所以a是訪問不到的 b.key2.push(8) console.log(b)// 這裡去操作b 在堆記憶體的key2屬性 因為a b 都是同一個堆儲存 所以 a b 都可以看到 key2陣列中新增了一個8複製程式碼
資料結構
上面出現一個問題就是 a 拷貝到b 在b中的操作引用型別 就會導致a也會改變 因為指標指向同一塊堆記憶體
但是改變b中基本資料型別 並不會引起a 的改變 在a中是訪問不到的 因為a b 基本資料型別是放在棧記憶體中 是相互獨立互不影響的
所以深拷貝就出現了
深拷貝
如果物件屬性值型別是引用型別的話 只會傳址(指標) 就會影響原物件 那現在就要 把原物件中屬性為引用型別的 要迴圈的賦給 其他物件var a = { key1: '123', key2: [4,5] } function deepcopy (a, b){ var b =b || {} for (var i in a) { if (typeof a[i] === 'object') { //判斷屬性key2 是否物件 b[i] = (a[i].__proto__.constructor == Array) ? []: {} deepcopy(a[i], b[i]) //遞迴 } else { b[i] = a[i] } } return b } var b = {} deepcopy(a,b) console.log(b) //{key1: "123", key2: Array(2)} console.log(a) //{key1: "123", key2: Array(2)} a.key3 = '333' console.log(a) //{key1: "123", key2: Array(2), key3: '333'} console.log(b) //{key1: "123", key2: Array(2)} 基本資料型別a 中新增了個key3 這也看不出啥 基本型別在棧中 不會影響到b b.key2.push('44') console.log(a) //{key1: "123", key2: Array(2), key3: '333'} console.log(b) //{key1: "123", key2: Array(3)} 這樣在b 中新增了 對a 沒有了影響 基本資料型別是沒有影響的 引用型別感覺一個一個給拆出來弄成了棧存 不是通過指標指向堆存複製程式碼
好了 有錯誤的希望給指出
參考連結:
關於JS堆疊與拷貝