js浅拷贝, 深拷贝

本文解析JavaScript中浅拷贝与深拷贝的区别,通过实例展示浅拷贝导致的obj1和obj2共享内存,而深拷贝创建独立副本。讲解了slice、JSON.parse和stringify、解构赋值及递归方法实现深拷贝。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

function的时候并不会拷贝过来。

浅度拷贝复制一层对象的属性,并不包括对象里面的为引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变。·

深度拷贝:重新开辟一个内存空间,需要递归拷贝对象里的引用,直到子属性都为基本类型。两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

JavaScript存储对象都是存地址的,所以浅拷贝会导致 obj1 和obj2 指向同一块内存地址。改变了其中一方的内容,都是在原来的内存上做修改会导致拷贝对象和源对象都发生改变,而深拷贝是开辟一块新的内存地址,将原对象的各个属性逐个复制进去。对拷贝对象和源对象各自的操作互不影响。

 

var obj = {
    a: 1,
    b: 2
}
var obj1 = Object.assign(obj); //浅拷贝
console.log(obj === obj1) // true

var obj2 = Object.assign({}, obj);
console.log(obj === obj2) // false

 深拷贝实现:
1. Array的slice和concat方法
  Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。之所以把它放在深拷贝里,是因为它看起来像是深拷贝。而实际上它是浅拷贝。


var array = [1,2,3]; 
var array_shallow = array; 
var array_concat = array.concat(); 
var array_slice = array.slice(0); 
console.log(array === array_shallow); //true 
console.log(array === array_slice); //false,“看起来”像深拷贝
console.log(array === array_concat); //false,“看起来”像深拷贝

2. JSON对象的parse和stringify, function不会拷贝过来。 

var obj1 = [{
    name: 'AAA',
    childs: ['CC', 'VV']
}] 
var obj2 = JSON.parse(JSON.stringify(obj1)) 
obj2[0].childs = [] 
console.log(obj1, obj2)

// [{childs: ["CC", "VV"], name: "AAA"}],
// [{childs: [], name: "AAA"}]

3.解构赋值 , 问题就是只能赋值一层

var obj1 = {a: 1, b: 2} 
var obj2 = {...obj1} 
obj2.a = 4 
console.log(obj1, obj2)

// {a: 1,b: 2}
// { a: 4, b: 2}
var obj1 = [{
    name: 'AAA',
    childs: ['CC', 'VV']
}] 
var obj2 = [...obj1]
obj2[0].childs = [] 
console.log(obj1, obj2)
console.log(obj1 === obj2) //false

//{  childs: [],  name: "AAA"}]
//{  childs: [],  name: "AAA"}]

4.递归

function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

https://www.jianshu.com/p/1c142ec2ca45

浅拷贝深拷贝是针对JavaScript中的对象属性为对象的情况而言的。浅拷贝只是复制了对象的引用,也就是复制了内存地址,所以拷贝后的对象和原对象会共用同一个内存地址,属性值的改变会相互影响。而深拷贝则是创建了一个完全独立的对象,拷贝了所有的属性和属性值,所以拷贝后的对象和原对象是完全独立的,互不影响。 在JavaScript中,可以通过不同的方法实现浅拷贝深拷贝浅拷贝可以使用手动实现、Object.assign()和拓展运算符等方法。手动实现的浅拷贝方法是遍历原始对象的属性,将属性值赋给新对象。Object.assign()方法可以将一个或多个源对象的属性复制到目标对象中,也可以用于实现浅拷贝。拓展运算符(...)也可以用于实现浅拷贝深拷贝则需要递归地复制对象的属性和属性值。可以通过手动实现一个深拷贝函数,在遍历原始对象的属性时,如果属性值是对象类型,则递归调用深拷贝函数进行复制。这样可以创建一个完全独立的对象,拷贝了所有的属性和属性值。 总结起来,浅拷贝只是复制了对象的引用,而深拷贝是创建了一个完全独立的对象。使用不同的方法可以实现浅拷贝深拷贝,根据具体的需求选择合适的方法进行使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JavaScript深拷贝浅拷贝概念与用法实例分析](https://download.youkuaiyun.com/download/weixin_38735570/14820137)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [javascript的深拷贝浅拷贝](https://blog.youkuaiyun.com/weixin_47417033/article/details/124899204)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值