美文网首页
用递归解决对象的深拷贝问题

用递归解决对象的深拷贝问题

作者: 每日log | 来源:发表于2020-12-28 12:45 被阅读0次

首先,有关【递归】的知识请参考上一节,链接地址:

【上一篇】:带你刷LeetCode中的递归算法

根据JS中【栈】的知识,我们知道js的基本数据类型是值引用,引用类型是地址引用。在浅拷贝中引用的地址同一个地址引用,修改其中一个对象的属性值,另一个对象也会产生影响;而在深拷贝中,会开辟一个新的内存地址用来存放新对象的值,两个对象对应引用的内存地址不一样 ,修改一个对象并不会对另外一个对象产生影响。更详细的描述请参考关于【栈】的介绍。

【栈】:JS版数据结构-栈

一、浅拷贝

01. 概念

一个新的对象直接拷贝已存在的对象的对象属性的引用,即浅拷贝。

02. 浅拷贝的实现方式

  • 通过for循环复制给另一个对象
var obj = {
    name: 'zhansan',
    msg:{
        txt: '123'
    }
};
var o = {};
for (var k in obj) {
    o[k] = obj[k];
}
console.log(o);  //{name: "zhansan", msg: {txt: 123}} 

  • 通过Object.assign()
var o = {}
Object.assign(o, obj);
console.log(o);// {name: "zhansan", msg: {txt: 123}} 

对于以上两个拷贝,obj中的name是基本数据类型,浅拷贝可以直接赋值得到,msg是个对象,是复杂数据类型,对象会开辟一个新的内存空间存储msg对象,浅拷贝的时候时拷贝的地址是同一个地址。此时改变obj中的txt中的值,o中的txt的值也会改变。

obj.msg.txt = '456'
console.log(obj.msg.txt) // 456
console.log(o.msg.txt) // 456
  • Array.prototype.slice.call()
var arr= [1, { x: 'zhao' }];
var arrNew = Array.prototype.slice.call(arr);
arrNew[1].x = 'zhang';
console.log(arrNew); // [ 1,{ x: 2 } ];
console.log(arr); // [ 1,{ x: 2 } ];

对于数组的拷贝,可以利用数组原型上内置的slice方法。

  • arr.concat()
let arr1 = [1, { a: 2 }];
let arr2 = [3, { b: 4 }];
let arr3 = arr1.concat(arr2);
arr1[1].a = 222;
console.log(arr1);// [ 1, { a: 222 } ]
console.log(arr2);// [ 3, { b: 4 } ]
console.log(arr3);// [ 1,{ a: 222 }, 3,{ b: 4 } ]

数组合并也是一个浅拷贝。

二、深拷贝

01. 概念

深拷贝会另外拷贝一份一个一模一样的对象,从堆内存中开辟一个新的区域存放新对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
简单说:深拷贝把存放对象的空间地址,再复制一份给新对象,这样两个对象直接互不干扰。

02. 深拷贝的实现方式

基于基本数据类型直接循环复制,对于复杂数据类型再次运用for循环操作,每一级都要循环拷贝。我们可以使用递归,对于遇到对象再次调用for循环即可。

function deepCopy(newobj, oldobj) {
    for (var k in oldobj) {
        var item = oldobj[k];
        if (item instanceof Array) {
            newobj[k] = [];
            deepCopy(newobj[k], item)
        } else if (item instanceof Object) {
            newobj[k] = {};
            deepCopy(newobj[k], item)
        } else {
            newobj[k] = item;
        }
    }
}
deepCopy(o, obj);
obj.msg.txt = 456
console.log(obj.msg.txt) //456
console.log(o.msg.txt) // 123

下一篇:JS中的算法.排序

推荐阅读:

1. JS. 类

2. JS. 构造函数

3. JS中对象原型proto及原型链

4. JS. 构造函数的原型 prototype

相关文章

  • 用递归解决对象的深拷贝问题

    首先,有关【递归】的知识请参考上一节,链接地址: 【上一篇】:带你刷LeetCode中的递归算法[http://m...

  • Javascript常见API实现

    JS 深拷贝的实现 简易版 问题 WARNING无法解决循环引用的问题,无限递归导致系统栈溢出无法拷贝特殊的对象,...

  • js实现一个通用的深拷贝

    对象深拷贝 用递归实现深拷贝,这里的函数做了bind的处理,使其返回一个新的函数,至于值是对象的话会进行递归遍历,...

  • 递归实现对象深拷贝

    ex:递归实现对象深拷贝

  • JS深拷贝的实现方法

    1、使用递归的方式实现深拷贝 2、通过 JSON 对象实现深拷贝 注意:JSON对象实现深拷贝无法实现对对象中方法...

  • Javascript中的深拷贝

    JS 中深拷贝的几种实现方法 1、使用递归的方式实现深拷贝 //使用递归的方式实现数组、对象的深拷贝 functi...

  • 实现深拷贝的几种方法(JS)

    使用递归 通过 JSON 对象实现深拷贝 lodash函数库实现深拷贝

  • 拷贝

    .深拷贝 深拷贝是对于一个对象所有层次的拷贝(递归) .浅拷贝 浅拷贝是对一个对象的顶层拷贝通俗的理解就是:拷贝了...

  • 深拷贝和浅拷贝

    浅拷贝 浅拷贝是对一个对象的顶层拷贝 深拷贝 深拷贝是对于一个对象所有层次的拷贝(递归) 拷贝的其他方式 浅拷贝对...

  • 浅拷贝和深拷贝

    浅拷贝和深拷贝都是只针对Object,Array这样的复杂对象。浅拷贝只复制一层对象的属性,而深拷贝则是递归复制了...

网友评论

      本文标题:用递归解决对象的深拷贝问题

      本文链接:https://www.haomeiwen.com/subject/fmiznktx.html