这是我参与「第五届青训营 」伴读笔记创作活动的第8天。
概念:
1)浅拷贝:将原对象或原数组的引用直接赋值给新对象、新数组,新对象/数组只是原对象的一个引用;
2)深拷贝:创建一个新的对象和竖住,将原对象的各项属性“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”。
赋值和浅拷贝的区别:
- 当我们把一个对象赋值给一个个新的变量时,赋的其实是在该对象的所在栈的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,连个对象是联动的;
- 浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址,一次如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制,即只复制对象空间而不是复制资源。
手写浅拷贝方法:
var obj = {
name:"小李",
age:19,
friend:['王五','赵六','张六']
}
var obj1 = shallowCopy(obj)
function shallowCopy(a){
var newObj = {};
for(var p in a){
console.log(p);
if(a.hasOwnProperty(p)){
newObj[p] = a[p];
}
}
return newObj;
}
obj1.name = '小管'
obj1.friend[0] = '王熊熊'
console.log('obj',obj);
console.log('obj1',obj1);
浅拷贝的实现方式
1.Object.assign()
Object.assign()方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。
var obj ={
name:'jack',
age:25,
hobby:{
ball:'tennis'
}
}
let obj1 = Object.assign({},obj)
obj2.hobby.ball = 'basketball'
console.log('obj',obj.hobby.ball) //basketball
console.log('obj1',obj1.hobby.ball) //basketball
2.Array.prototype.slice()
var arr = ['jack',25,{hobby:'tennise'}];
let arr1 = arr.slice()
arr1[2].hobby='rose'
arr1[0]='rose'
console.log( arr[2].hobby) //rose
console.log( arr[0]) //jack
3.Array.prototype.concat()
var arr = ['jack',25,{hobby:'tennise'}];
let arr1 = arr.concat()
arr1[2].hobby='rose'
arr1[0]='rose'
console.log( arr[2].hobby) //rose
console.log( arr[0]) //jack
4.解构
let aa = {
age: 18,
name: 'aaa',
address: {
city: 'shanghai'
}
}
let bb = {...aa};
bb.address.city = 'shenzhen';
console.log(aa.address.city); // shenzhen
深拷贝的实现方法
1.JSON.parse(JSON.stringify())
var arr = ['jack',25,{hobby:'tennise'}];
let arr1 = JSON.parse(JSON.stringify(arr))
arr1[2].hobby='rose'
arr1[0]='rose'
console.log( arr[2].hobby) //tennise
console.log( arr[0]) //jack
2.借助第三方库lodash
// 安装lodash
npm i --save lodash
// 引入lodash
var _ = require('lodash');
var obj1 ={
name:'jack',
age:25,
}
let obj2 =_.cloneDeep(obj1)
obj2.name = 'rose'
console.log('obj1',obj1.name) //jack
console.log('obj2',obj2.name) //rose