深拷贝和浅拷贝|青训营笔记

52 阅读2分钟

这是我参与「第五届青训营 」伴读笔记创作活动的第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);

image.png

image.png

浅拷贝的实现方式

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