浅拷贝和深拷贝的区别

1、浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
2、深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。

3、区别:可变对象就不会这样会修改值后另存到一个新的地址上,而是直接再原对象的地址上把值给改变了,这个对象依然执行这个地址

4、本质区别:可变对象修改了值,不会新建一个内存地址的对象,不可变对象如果修改了值,及时复制了一份新的内存地址,原始地址的值不会被改变。

5、不可变元素包含:int,float,complex,long,str,unicode,tuple

6、可变原生:list

例子:

import copy
a = [1, 2, 3, 4, ['a', 'b']]
b = a #赋值,传对象的引用
c = copy.copy(a) #浅拷贝,对象拷贝
d = copy.deepcopy(a) #深拷贝,对象拷贝

a.append(5) #修改对象a,列表末尾添加数字5
a[4].append('c') #修改对象a中的列表['a', 'b']

print 'a= ', a
print 'b= ', b
print 'c= ', c
print 'd= ', d

输出结果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5] #修改了原始对象,变为修改后的列表
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5] #对象的引用,对象的任何值变化都随着变化
c = [1, 2, 3, 4, ['a', 'b', 'c']] #浅拷贝,不可变元素不能改变,可变元素随着原始对的变化而变化了
d = [1, 2, 3, 4, ['a', 'b']] #深拷贝,原始对象的值发生任何变化,深拷贝新的对象内存地址不会发生任何变化

### JavaScript中浅拷贝深拷贝区别及实现方法 #### 1. 浅拷贝 浅拷贝是指创建一个新的对象,该对象拥有原始对象属性值的副本。然而,对于引用类型的属性(如数组或对象),仅复制其引用地址,而不是递归地复制嵌套的对象[^2]。 - **特点**:浅拷贝只复制对象的第一层属性,如果属性是引用类型,则新对象原对象共享这些引用类型的内存地址。 - **实现方式**: - 使用 `for...in` 循环手动复制属性。 - 使用 `Object.assign()` 方法。 - 使用扩展运算符 `...`。 ```javascript // 示例:使用 Object.assign 实现浅拷贝 const obj = { a: 1, b: { c: 2 } }; const shallowCopy = Object.assign({}, obj); shallowCopy.b.c = 3; console.log(obj.b.c); // 输出: 3 ``` 从上述代码可以看出,修改浅拷贝中的嵌套对象会影响原始对象,因为它们共享相同的引用地址。 #### 2. 深拷贝 深拷贝是指创建一个全新的对象,该对象不仅包含原始对象的所有属性值,还递归地复制了所有嵌套对象的值,确保新对象与原对象完全独立[^3]。 - **特点**:深拷贝会递归地复制对象的所有层级,即使对象中包含其他对象或数组,也会被完整复制,互不影响。 - **实现方式**: - 使用递归函数手动实现。 - 使用第三方库(如 Lodash 的 `cloneDeep` 方法)。 - 使用 `JSON.parse(JSON.stringify())` 方法(注意:这种方法无法处理函数、`undefined` 循环引用等特殊类型[^1])。 ```javascript // 示例:使用 JSON.parse(JSON.stringify()) 实现深拷贝 const obj = { a: 1, b: { c: 2 } }; const deepCopy = JSON.parse(JSON.stringify(obj)); deepCopy.b.c = 3; console.log(obj.b.c); // 输出: 2 [^1] ``` 从上述代码可以看出,修改深拷贝中的嵌套对象不会影响原始对象,因为它们之间没有共享任何引用。 #### 3. 区别总结 - **引用关系**:浅拷贝仅复制第一层属性,嵌套对象仍共享引用;深拷贝则递归地复制所有嵌套对象,确保完全独立[^3]。 - **性能**:浅拷贝通常比深拷贝更高效,因为它只需要复制一层引用,而不涉及递归操作[^2]。 - **适用场景**: - 浅拷贝适用于不需要修改嵌套对象或可以接受共享引用的场景。 - 深拷贝适用于需要完全独立的对象副本以避免副作用的场景。 #### 4. 注意事项 - `JSON.parse(JSON.stringify())` 方法虽然简单,但存在局限性,例如无法正确处理函数、`undefined` 循环引用等特殊类型[^1]。 - 在实际开发中,推荐使用成熟的第三方库(如 Lodash 的 `cloneDeep` 方法)来实现深拷贝,以避免潜在的问题。 ```javascript // 示例:使用 Lodash 的 cloneDeep 方法实现深拷贝 const _ = require('lodash'); const obj = { a: 1, b: { c: 2 } }; const deepCopy = _.cloneDeep(obj); deepCopy.b.c = 3; console.log(obj.b.c); // 输出: 2 [^3] ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值