JavaScript:深浅拷贝与Object.assign()方法介绍

深浅拷贝

1、什么是深浅拷贝

深浅拷贝都只是针对引用对象来区分的,其他基本类型并不区分什么深浅拷贝。

浅拷贝
浅拷贝是对内存地址的复制,让目标对象指针和源对象指向同一片内存地址。

当内存销毁的时候,指向对象的指针必须重新定义才能够使用。

深拷贝
深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后两个对象虽然存的值是一样的,但是内存地址不一样。

2、深浅拷贝的实现

  • 浅拷贝实现方式

直接赋值即可实现对象浅拷贝

// 浅拷贝
let obj1 = {
    
     a: 0, b: {
    
     c: 0 } }
let obj2 = obj1
console.log(obj1); // { a: 0, b: { c: 0 } }
console.log(obj2); // { a: 0, b: { c: 0 } }

// 修改obj1中的a属性
obj1.a = 1

// 可以看到obj2中的a属性的值也改变了,这样就能证明obj2只是对obj1对象内存地址的复制,指针还是指向obj1对象内存地址
console.log(obj2); // { a: 1, b: { c: 0 } }
  • 深拷贝实现方式

方式一:JSON.stringify()方法和JSON.parse()方法实现

let obj1 = {
    
    a:0,b:{
    
    c:"hello"}}

let obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj2); // { a: 0, b: { c: 'hello' } }

obj1.a = 1
console.log(obj1); // { a: 1, b: { c: 'hello' } }
console.log(obj2); // { a: 0, b: { c: 'hello' } }

// 可以看到,obj1的a属性取值改变并不会影响到obj2中的a属性取值,
// 所以也就可以说明这两个对象内存地址并不一样

方式二:通过assign()方法实现(特殊)
关于assign()方法的介绍可以看MDN官方

这个方法比较特殊,当对象嵌套层次小于2层,则是深拷贝,大于等于2层时则是浅拷贝,具体原理:利用拼接原理,对对象进行拼接,将后续对象的内容插入到第一哥参数指定的对象,并且不会修改第一个参数之后的对象。

let obj1 = {
    
     a: 0, b: {
    
     c: "hello" } }
let obj2 = Object.assign({
    
    }, obj1)

obj1.a = 1 // 小于2层的为深拷贝
obj1.b.c = '你好' // 大于等于层的为浅拷贝
console.log(obj1); //  { a: 1, b: { c: '你好' } }
console.log(obj2); // { a: 0, b: { c: '你好' } }

方式三:自定义深拷贝(循环实现)

function myDeepClone(Obj) {
    
    
    var newObj;

    if (Obj instanceof Array) {
    
     //确定类型

        newObj = [];  // 创建一个空的数组

        var i = Obj.length;

        while (i--) {
    
    

            newObj[i] = myDeepClone(Obj[i]); //递归回调

        }

        return newObj; //结束函数完成深拷贝

    } else if (Obj instanceof Object) {
    
     //确定类型

        newObj = {
    
    };  // 创建一个空对象

        for (var k in Obj) {
    
      // 为这个对象添加新的属性

            newObj[k] = myDeepClone(Obj[k]); //递归回调

        }

        return newObj; //结束函数完成深拷贝

    } else {
    
    

        return Obj; //结束函数完成深拷贝

    }

}

let obj1 = {
    
     a: 0, b: {
    
     c: "hello" } }
let obj2 = myDeepClone(obj1)

obj1.b.c = "你好"
console.log(obj1); // { a: 0, b: { c: "你好" } }
console.log(obj2); // { a: 0, b: { c: "hello" } }

猜你喜欢

转载自blog.csdn.net/lalala_dxf/article/details/124649711