JavaScript:利用遞歸實現對象深拷貝

先來普及一下深拷貝和淺拷貝的區別jquery

淺拷貝:就是簡單的複製,用等號便可完成es6

let a = { a: 1 }
let b = a
複製代碼

這就完成了一個淺拷貝 可是當修改對象b的時候,咱們發現對象a的值也被改變了npm

b.a = 10
console.log(a.a) => 10
複製代碼

這是由於淺拷貝只複製了指向對象的指針,新舊對象共用同一塊內存,修改某一個對象的同時也會把另外一個都一併修改了bash

深拷貝:跟淺拷貝最簡單明瞭的區別就是修改拷貝的對象,不會改變源對象 利用Object.assign能夠對只有一層的對象實現深拷貝,以下:函數

let a = { a: 1, b: 2, c: 3 }
let b = Object.assign({}, a)
b.b = 100
console.log(a.b) => 2
複製代碼

能夠看出來這樣是徹底能夠作到對只有一層的對象實現深拷貝的 可是若是對象裏面的元素仍是對象的話就沒做用了測試

let a = { a: 1, b: 2, c: 3, d: { a: 1 } }
let b = Object.assign({}, a)
b.d.a = 100
console.log(a.d.a) => 100
複製代碼

對於這種比較複雜的對象,咱們就能夠利用遞歸的方式實現真正的對象深拷貝了ui

function deepClone (sourceObj, targetObj) {
    let cloneObj = targetObj || {}
    if (!sourceObj || typeof sourceObj !== "object" || sourceObj.length === undefined) {
        return sourceObj
    }
    if (sourceObj instanceof Array) {
        cloneObj = sourceObj.concat()
    } else {
        for (let i in sourceObj) {
            if (typeof sourceObj[i] === 'object') {
                cloneObj[i] = deepClone(sourceObj[i], {})
            } else {
                cloneObj[i] = sourceObj[i]
            }
        }
    }
    return cloneObj
}
複製代碼

簡單的幾行代碼就能夠輕鬆實現對象的深拷貝es5

簡單的測試代碼,以下:
let sourceObj = {
  a: 1,
  b: {
    a: 1
  },
  c: {
    a: 1,
    b: {
      a: 1
    }
  },
  d: function() {
    console.log('hello world')
  },
  e: [1, 2, 3]
}
let targetObj = deepClone(sourceObj, {})
targetObj.c.b.a = 9
console.log(sourceObj) => { a: 1,  b: { a: 1 },  c: { a: 1, b: { a: 1 } },  d: [Function: d],  e: [ 1, 2, 3 ] }
console.log(targetObj) => { a: 1,  b: { a: 1 },  c: { a: 1, b: { a: 9 } },  d: [Function: d],  e: [ 1, 2, 3 ] }
複製代碼

另外介紹兩個用來作深拷貝的庫spa

**jquery**
使用方法:
let targetObj = $.extent(true,{},sourceObj)
**lodash函數庫**
使用方法:
npm install lodash
**es5寫法**
let lodash = require('lodash')
**es6寫法**
import lodash from 'lodash'

let targetOj = lodash.cloneDeep(sourceObj)
複製代碼

各位看官以爲有什麼地方不對的請多多指教。指針

相關文章
相關標籤/搜索