深拷贝和浅拷贝及简单实现

1. 深拷贝和浅拷贝简单理解

  浅拷贝的对象若包含子对象,当新的对象对子对象发生改变时则会使原对象子对象一同改变,若新的对象只改变第一层的数据,则源对象不会改变。
  换句话说:浅拷贝过来的数据只有第一层数据不是共享的,第二层乃至第三层的数据和源对象是共享的。而深拷贝是和源对象没有任何共享的

  1. 浅拷贝:
    将原对象或原数组的引用直接赋给新对象或新数组,新对象或数组只是原对象的一个引用
  2. 深拷贝:
    创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来, 是“值”而不是“引用”。
  3. 深拷贝的要求程度:
    是仅“深”拷贝第一层级的对象属性或数组元素,还是递归拷贝所有层级的对象属性和数组元素?
  4. 怎么检验深拷贝成功:
    改变任意一个新对象/数组中的属性/元素, 都不改变原对象/数组。

2. 深拷贝的实现

2.1 弱鸡版

let a = [1, '2', 'stu', 'ku', 'pu'];
let b = JSON.parse(JSON.stringify(a));
a[0] = 9
console.log(a); // [ 9, '2', 'stu', 'ku', 'pu' ]
console.log(b); // [ 1, '2', 'stu', 'ku', 'pu' ]

2.2 递归调用函数版

function deepClone(obj) {
    if (obj == null) return null; //直接退出
    if(obj instanceof Date) return new Date(obj);//如果拷贝的是Date日期对象 那么直接返回一个新的日期就好啦
    if(obj instanceof RegExp) return new RegExp(obj); //如果传进来的参数是正则表达式,那就返回一个正则表达式
    if(typeof obj !== "object") return obj; // 如果是非对象,直接返回

    let newObj = obj instanceof Array ? [] : {}; // 验证传递过来的参数是数组还是对象,从而判断创建新的数组或对象
    // 如果是对象,则for in遍历这个对象
    for(let key in obj) { // key就是对象的每一个可枚举的属性名
        // 如果obj是对象,则继续递归深拷贝这个对象,否则返回
        newObj[key] = typeof obj[key] === "object" ? deepClone(obj[key]) : obj[key];
        
    }

    return newObj;
}
let a = [1, 2, 3, 5, "a", "SongTang", [1, 2], {cost: 65}, null];
let c = a;
let b = deepClone(a);
a[6][0] = 10;
a[2] = 2;
console.log(a); // [1, 2, 2, 5, "a", "SongTang", [10, 2], {cost: 65}, null];
console.log(b); // [1, 2, 3, 5, "a", "SongTang", [1, 2], {cost: 65}, null];
console.log(c); // 和 a一样
//结论: 成功实现了深拷贝

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,深拷贝浅拷贝是两种不同的对象拷贝方式,它们的区别在于拷贝后对象的内存管理方式不同。 浅拷贝是指将一个对象的值复制到另一个对象,包括对象中的成员变量。在浅拷贝中,两个对象将共享同一块内存空间,当其中一个对象修改了共享的资源时,另一个对象也会受到影响。这是因为浅拷贝只是简单地复制了指针,而没有复制指针所指向的内容。 深拷贝是指创建一个新的对象,并将原始对象中的值复制到新对象中。在深拷贝中,两个对象拥有独立的内存空间,彼此之间互不影响。深拷贝会递归地复制指针所指向的内容,确保每个对象都有自己的独立资源。 下面是C++代码实现深拷贝浅拷贝的示例: ```cpp #include <iostream> class MyClass { public: int* data; // 默认构造函数 MyClass() { data = new int(0); } // 拷贝构造函数(浅拷贝) MyClass(const MyClass& other) { data = other.data; } // 拷贝构造函数(深拷贝) MyClass(const MyClass& other) { data = new int(*other.data); } // 析构函数 ~MyClass() { delete data; } }; int main() { MyClass obj1; *obj1.data = 10; // 浅拷贝 MyClass obj2 = obj1; std::cout << *obj2.data << std::endl; // 输出:10 // 修改obj1的值 *obj1.data = 20; std::cout << *obj2.data << std::endl; // 输出:20(受到影响) // 深拷贝 MyClass obj3(obj1); std::cout << *obj3.data << std::endl; // 输出:20(不受影响) return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值