博客地址:https://ainyi.com/72html
JavaScript 程序中,對於簡單的數字、字符串能夠經過 = 賦值拷貝
可是對於數組、對象、對象數組的拷貝,就有淺拷貝和深拷貝之分es6
淺拷貝就是當改變了拷貝後的數據,原數據也會相應改變json
來講說深拷貝數組
不推薦此方法函數
let a = [1, 2, 3] let b = [] for (let val of a) { b.push(val) } b.push(4) a // [1, 2, 3] b // [1, 2, 3, 4]
數組方法 slice() 可從已有的數組中返回選定的元素
那麼設置爲 0,就是返回整個數組插件
let a = [1, 2, 3] let b = a.slice(0) b.push(4) a // [1, 2, 3] b // [1, 2, 3, 4]
數組方法 concat() 鏈接一個或多個數組,並返回一個副本
那麼不設置參數,就返回本數組code
let a = [1, 2, 3] let b = a.concat() b.push(4) a // [1, 2, 3] b // [1, 2, 3, 4]
let a = [1, 2, 3] let b = [...a] b.push(4) a // [1, 2, 3] b // [1, 2, 3, 4]
let a = [1, 2, 3] let b = Array.from(a) b.push(4) a // [1, 2, 3] b // [1, 2, 3, 4]
Object.assign(target, obj)htm
let a = { name: 'krry' } let b = Object.assign({}, a) b.name = 'lily' a // { name: 'krry' } b // { name: 'lily' }
注意使用 assign() 有以下特色:對象
let a = { name: 'krry' } let b = { ...a } b.name = 'lily' a // { name: 'krry' } b // { name: 'lily' }
以上是簡單數組、對象的深拷貝方法,可是對於二維數組、對象數組、對象裏包含對象,以上方法均達不到深拷貝方法
以上只能達到數組、對象的第一層的==深拷貝==,對於裏面的數組或對象屬性則是==淺拷貝==,由於裏面的內存地址只是拷貝了一份,但都是指向==同一個地址==
因此當改變數組、對象裏的數組元素或對象,原數據依然會改變繼承
使用 JSON.parse(JSON.stringify(obj))
let a = [1, [2, {aa: 2}, [4]], {aa: 5, cc: { dd: 6 }}] let b = JSON.parse(JSON.stringify(a)) // 完美
經過 JSON.stringify 實現深拷貝有幾點要注意
function deepCopy(obj) { let result = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === 'object') { result[key] = deepCopy(obj[key]); // 遞歸複製 } else { result[key] = obj[key]; } } } return result; }
使用 lodash 插件的深拷貝方法
// 官方例子 var objects = [{ 'a': 1 }, { 'b': 2 }]; var deep = _.cloneDeep(objects); console.log(deep[0] === objects[0]); // => false
傳送門:https://www.lodashjs.com/docs/4.17.5.html#cloneDeep
博客地址:https://ainyi.com/72