浅拷贝
start
- 工作的过程中,拷贝一份数据,用来逻辑处理,是经常会遇到的场景。
- 花点时间总结学习一下相关知识
赋值 =
- 简单数据类型,赋值,传递的是值
var a = '你好'
var b = a
console.log(1, b)
b = '修改简单类型的值'
console.log(2, b, a)
// 1 你好
// 2 修改简单类型的值 你好
2.复杂数据类型,赋值,传递的是引用地址
var a = {
name: '你好'
}
var b = a
console.log(1, b)
b.name = '修改复杂类型的值'
console.log(2, b, a)
// 1 { name: '你好' }
// 2 { name: '修改复杂类型的值' } { name: '修改复杂类型的值' }
总结
简单来说,我们使用 赋值运算符=
,拷贝复杂类型的值的时候,拷贝的是引用地址,操作拷贝后的对象会对原本对象有影响。
浅拷贝
但是往往工作中,并不希望操作拷贝后的数据会对原本数据有影响。
这个时候我们就需要拷贝一份,全新的复杂数据类型的数据出来,供我们使用了。
解决方式:
- 浅拷贝:浅拷贝是拷贝了对象的应用,当对象的属性是引用类型的时候,实质是复制其引用,当引用值发生改变时,拷贝值也跟着改变。
- 深拷贝:深拷贝时另外申请了一块内存,拷贝对象的内容与原来一摸一样,更改原对象,拷贝对象也跟着变化。
说说我自己的理解:
浅拷贝:拷贝了一个对象,但是只拷贝的对象的第一层,当对象的属性是引用类型,拷贝的这个属性,依旧是拷贝的地址引用。
深拷贝:深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。
常见的浅拷贝
Object.assgin
var obj1 = {
name: '开始',
version: 1,
other: {
say: '其他意见'
}
}
var obj2 = Object.assign({}, obj1)
console.log(1, obj2)
// 1 { name: '开始', version: 1, other: { say: '其他意见' } }
obj2.name = '修改第一层级属性'
obj2.other.say = '修改这个对象修改第二层级属性'
console.log(2, obj2, obj1)
// 2 { name: '修改第一层级属性', version: 1, other: { say: '修改这个对象修改第二层级属性' } } { name: '开始', version: 1, other: { say: '修改这个对象修改第二层级属性' } }
/* 浅拷贝 */
- 展开运算符
...
var obj1 = {
name: '开始',
version: 1,
other: {
say: '其他意见'
}
}
var obj2 = { ...obj1 }
console.log(1, obj2)
// 1 { name: '开始', version: 1, other: { say: '其他意见' } }
obj2.name = '修改第一层级属性'
obj2.other.say = '修改这个对象修改第二层级属性'
console.log(2, obj2, obj1)
// 2 { name: '修改第一层级属性', version: 1, other: { say: '修改这个对象修改第二层级属性' } } { name: '开始', version: 1, other: { say: '修改这个对象修改第二层级属性' } }
/* 浅拷贝 */
Array.prototype.slice()
var obj1 = ['开始', { say: 'old' }]
var obj2 = Array.prototype.slice.call(obj1)
obj2[0] = '修改第一层级属性'
console.log(1, obj2)
// 1 [ '修改第一层级属性', { say: 'old' } ]
obj2[1].say = '修改这个对象修改第二层级属性'
console.log(2, obj2, obj1)
// 2 [ '修改第一层级属性', { say: '修改这个对象修改第二层级属性' } ] [ '开始', { say: '修改这个对象修改第二层级属性' } ]
/* 浅拷贝 */