JS中徹底弄懂淺拷貝和深拷貝
阿新 • • 發佈:2019-01-11
1、淺拷貝和深拷貝的簡介
淺拷貝:兩個物件經過拷貝後雖然具有相同的屬性,但是他們都指向同一個記憶體空間
let a = {x: 123}
let b = a
b.x = 234
console.log(b) // {x: 234}
console.log(a) // {x: 234}
.操作會引起引用,同一地址的變數一起改變
深拷貝:兩個物件除了拷貝了一樣的屬性, 沒有任何其他關聯(指向不同的記憶體空間)。
2、深拷貝實現方法
(1). 物件深拷貝
a.普通物件(單層屬性)
方法1:ES5 for迴圈賦值
let souceObj = {x: 1, y: 2} function clone(souceObj, targetObj = {}) { for (const key in souceObj) { targetObj[key] = souceObj[key] } return targetObj } let targetObj = clone(souceObj) targetObj.x = 10 console.log(souceObj) //{ x: 1, y: 2 } console.log(targetObj) //{ x: 10, y: 2 }
方法2:JSON parse stringify
let souceObj = {x: 1, y: 2}
let targetObj = JSON.parse(JSON.stringify(souceObj))
targetObj.x = 10
console.log(souceObj) //{ x: 1, y: 2 }
console.log(targetObj) //{ x: 10, y: 2 }
方法3:ES6 操作符 ...
let souceObj = {x: 1, y: 2} let targetObj = {...souceObj} targetObj.x = 10 console.log(souceObj) //{ x: 1, y: 2 } console.log(targetObj) //{ x: 10, y: 2 }
方法4:ES6 Object.assign()
let souceObj = {x: 1, y: 2}
let targetObj = Object.assign({}, souceObj)
targetObj.x = 10
console.log(souceObj) //{ x: 1, y: 2 }
console.log(targetObj) //{ x: 10, y: 2 }
b.巢狀物件(多層屬性:屬性也是物件)
function deepCopy(source, target = {}) { let key; for (key in source) { // 意思就是__proto__上面的屬性,我不拷貝 if (source.hasOwnProperty(key)) { // 如果這一項是object型別,就遞迴呼叫deepCopy if (typeof(source[key]) === "object") { target[key] = Array.isArray(source[key]) ? [] : {}; deepCopy(source[key], target[key]); } else { // 如果不是object型別,就直接賦值拷貝 target[key] = source[key]; } } } return target; }
(2). 陣列深拷貝
方法1: 陣列的 slice方法
let souceArr = ['one', 'two', 'three']
let targetArr = souceArr.slice(0)
targetArr[1] = 'new two'
console.log(souceArr) //[ 'one', 'two', 'three' ]
console.log(targetArr) //[ 'one', 'new two', 'three' ]
方法2: 陣列的 concat方法
let souceArr = ['one', 'two', 'three']
let targetArr = souceArr.concat()
targetArr[1] = 'new two'
console.log(souceArr) //[ 'one', 'two', 'three' ]
console.log(targetArr) //[ 'one', 'new two', 'three' ]
物件陣列的深拷貝:
let souceArr = [{'name': 'weifeng'},{'name': 'boy'}];//原陣列
[].concat(JSON.parse(JSON.stringify(souceArr)))
方法3: ES6 操作符 ...
let souceArr = ['one', 'two', 'three']
let targetArr = [...souceArr]
targetArr[1] = 'new two'
console.log(souceArr) //[ 'one', 'two', 'three' ]
console.log(targetArr) //[ 'one', 'new two', 'three' ]
方法4: 基礎方法 迴圈遍歷
這裡就不貼程式碼了...