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: 基础方法 循环遍历
这里就不贴代码了...