JS經常使用的深、淺拷貝

在JS中,數據類型分爲基本數據類型和引用數據類型兩種。對於基本數據類型來講,它的值直接存儲在棧內存中,而對於引用類型來講,它在棧內存中只是存儲了一個指向對內存的引用,而真正的數據存儲在堆內存中。javascript

object、array 這兩個就是引用類型,當我門直接去拷貝的話(copyObj = obj), 拷貝的是指obj的引用,當你修改copyObj時候,obj也會同時改變;數組也同樣道理。vue

深拷貝

所謂的深拷貝,要實現的效果是無論對象或數組裏面嵌套了多少層引用類型,都能拷貝出來,而非只拷貝它的引用java

要實現深拷貝的方法經常使用有一下方法:數組

一、JSON.parse、JSON.stringify

let obj2 = JSON.parse(JSON.stringify(obj1))
複製代碼

缺點:undefined、function、symbol 會在轉換過程當中被忽略函數

二、遞歸深拷貝

// 不支持循環引用
function deepCopy (src) {
    if (!src || typeof src !== 'object') return src // 判斷是否爲array || object
    let temp = Array.isArray(src) ? [] : {}
    for (let key in src) {
        if (src.hasOwnProperty(key)) { // 過濾繼承來的屬性
            if (src[key] && typeof src[key] === 'object') { // 若屬性也是引用類型
                temp[key] = deepCopy(src[key]) // 遞歸克隆
            } else {
                temp[key] = src[key] // 非引用類型就直接拷貝
            }
        }
    }
    return temp
}

let obj2 = deepCopy(obj1)
複製代碼

淺拷貝

那麼淺拷貝,簡單引用類型直接賦值post

或者引用類型的首層進行了深拷貝,可是屬性中還有引用類型,只是拷貝它的引用,這樣的狀況下,也爲淺拷貝ui

如下淺拷貝方法,都只是實現了首層的深拷貝,當嵌套引用類型就要只會拷貝它的引用spa

一、ES6擴展運算符

let obj2 = {...obj1} // 對象淺拷貝
let arr2 = [...arr1] // 數組淺拷貝
複製代碼

二、Object.assign()

let obj2 = Object.assign({}, obj1)
複製代碼

三、遍歷

let shallowCopy = obj => {
  let temp = {}
  // 遍歷對象
  for (let key in obj) {
    // 只複製自己擁有的屬性(非繼承過來的屬性)枚舉屬性
    if (obj.hasOwnProperty(key)) {
      temp[key] = obj[key]
    }
  }
  return temp
}
let obj2 = shallowCopy(obj1)
複製代碼

三、concat()

let arr2 = [].concat(arr1)
複製代碼

相關連接:code

JS的防抖、節流函數對象

八步開發一個vue的組件庫

VUE的實現原理(數據劫持、觀察者模式)

Javascript實現簡單的冒泡排序、插入排序

一個很是簡單的-發佈訂閱模式

相關文章
相關標籤/搜索