什么是浅拷贝和深拷贝
- 拷贝:指拷贝源对象到目标对象,又分为浅拷贝和深拷贝两种
- 浅拷贝:如拷贝的对象有属性值是非基础类型(即对象),则浅拷贝拷贝的是对象的引用,而非对象本身,拷贝完成以后更改目标对象,源对象也会被更改
- 深拷贝:深拷贝完美解决了浅拷贝存在的问题,目标对象是一个全新的对象,更改目标对象不会影响到源对象
浅拷贝
Object.assign()
// 对象的属性值都是基础类型
console.log('--------对象的属性值都是基础类型--------')
const src1 = { a: 'aa' }
const target1 = Object.assign({}, src1)
// 输出源对象
console.log('源对象: ', src1) // {a: "aa"}
// 输出拷贝后的目标对象
console.log('目标对象: ', target1) // {a: "aa"}
// 更改目标对象
target1.a = 'aaa'
console.log('更改目标对象后的结果: ')
// 输出更改后的目标对象
console.log('目标对象: ', target1) // {a: "aaa"}
// 输出源对象,发现源对象没有被改变
console.log('源对象: ', src1) // {a: "aa"}
// 对象的属性值为非基础类型
console.log('--------对象的属性值为非基础类型--------')
const src2 = {flag: 'src2', a: { b: 'bb' } }
const target2 = Object.assign({}, src2)
// 输出源对象
console.log('源对象: ', src2) // {flag: "src2", a: {b: "bb"}}
// 输出目标对象
console.log('目标对象: ', target2) // {flag: "src2", a: {b: "bb"}}
// 更改目标对象
target2.flag = 'target2'
target2.a.b = 'bbb'
console.log('更改目标对象后的结果: ')
// 输出更改后的目标对象
console.log('目标对象: ', target2) // {flag: "target2", a: {b: "bbb"}}
// 输出源对象,发现源对象被改了
console.log('源对象: ', src2) // {flag: "src2", a: {b: "bbb"}}
in运算符
// 通过for in循环复制对象
function copy (target, src) {
for (let key in src) {
// 过滤掉原型链上的属性,只复制src对象自身的属性和值
if (src.hasOwnProperty(key)) {
target[key] = src[key]
}
}
return target
}
// 对象的属性值都是基础类型
console.log('--------对象的属性值都是基础类型--------')
const src1 = { a: 'aa' }
const target1 = copy({}, src1)
// 输出源对象
console.log('源对象: ', src1) // {a: "aa"}
// 输出拷贝后的目标对象
console.log('目标对象: ', target1) // {a: "aa"}
// 更改目标对象
target1.a = 'aaa'
console.log('更改目标对象后的结果: ')
// 输出更改后的目标对象
console.log('目标对象: ', target1) // {a: "aaa"}
// 输出源对象,发现源对象没有被改变
console.log('源对象: ', src1) // {a: "aa"}
// 对象的属性值为非基础类型
console.log('--------对象的属性值为非基础类型--------')
const src2 = {flag: 'src2', a: { b: 'bb' } }
const target2 = copy({}, src2)
// 输出源对象
console.log('源对象: ', src2) // {flag: "src2", a: {b: "bb"}}
// 输出目标对象
console.log('目标对象: ', target2) // {flag: "src2", a: {b: "bb"}}
// 更改目标对象
target2.flag = 'target2'
target2.a.b = 'bbb'
console.log('更改目标对象后的结果: ')
// 输出更改后的目标对象
console.log('目标对象: ', target2) // {flag: "target2", a: {b: "bbb"}}
// 输出源对象,发现源对象被改了
console.log('源对象: ', src2) // {flag: "src2", a: {b: "bbb"}}
深拷贝
JSON
// 直接上对象的属性值为非基础类型的对象
const src = { flag: 'src', a: { b: 'bb' } }
console.log('源对象: ', src)
const target = JSON.parse(JSON.stringify(src))
console.log('目标对象: ', target)
console.log('--------更改目标对象--------')
target.flag = 'target'
target.a.b = 'bbb'
console.log('目标对象: ', target)
// 返现源对象没有被改变
console.log('源对象: ', src)
来源:CSDN
作者:前端大菜鸟
链接:https://blog.csdn.net/qq_25076971/article/details/104105402