浅析JS深拷贝与浅拷贝

6 篇文章 0 订阅
4 篇文章 0 订阅

深拷贝和浅拷贝是只针对Object和Array引用类型的,为什么这么说呢,要理解深拷贝与先拷贝,首先我们要搞懂数据类型的存储方式

数据类型

数据类型分为基本数据类型和引用数据类型

  • 基本数据类型:String,Number,Boolean,Null,Undefined
  • 引用数据类型:Object
这两种类型存储方式的区别

基本类型数据直接存储在栈内,而引用型数据类型是在栈中存放指针,通过指针指向,在堆中找到真实的数据内容,所以说深拷贝和浅拷贝只针对与引用类型

浅拷贝

对于浅拷贝而言,只是单单拷贝了对象的引用,新的对象与原有对象,同时指向同一个堆内存空间,若数据内容改变,新老对象一起发生变化

深拷贝

而我们开发过程中浅拷贝并不能满足我们需求,由此,深拷贝出现了,深拷贝会将原有数据的引用和数据内容一并拷贝,形成一个新的引用对象

深拷贝的实线

上面我们理解了深浅拷贝的原理,那如何做到实现呢,下面例举一些常用的实现方法

1、JSON.stringify()以及JSON.parse()
var obj1 = {
  name: 'Echo',
  age: 16
}
var obj2 = JSON.parse(JSON.stringify(obj1)) // 将obj1深拷贝
obj2.name = 'Kim' // 改变新对象的值
console.log(obj1) // {name: 'Echo', age: 16}
console.log(obj2) // {name: 'Kim', age: 16}

注意:这种实现是存在局限性的,这种深拷贝是通过JSON.stringify(value)和JSON.parse(value)实现的,value不能为空,所以如果是Undefined,Function,RegExp,Error序列化只能得到空对象,就不适用了
eg:

var obj1 = {
  name: 'Echo',
  function(){
    console.log('深拷贝')
  },
  undefined
}
var obj2 = JSON.parse(JSON.stringify(obj1)) // 将obj1深拷贝
console.log(obj1) // {name: "echo", function: ƒ, undefined: undefined}
console.log(obj2) // {name: 'echo'}
2、Object.assign(target, source)
var obj1 = {
  name: 'Echo',
  age: 16
}
var obj2 = Object.assign ({}, obj1) // 将obj1深拷贝
obj2.age = 18 // 改变新对象的值
console.log(obj1) // {name: 'Echo', age: 16}
console.log(obj2) // {name: 'Echo', age: 18}

注意:这种实现也是存在局限性的,如果原对象中含有多层嵌套对象结构,则高层结构仅仅是浅拷贝
eg:

var obj1 = {
  name: 'Echo',
  age: 16,
  arr: [1, 2, 3]
}
var obj2 = Object.assign ({}, obj1) // 将obj1深拷贝
obj2.arr[0] = 18 // 改变新对象的值
console.log(obj1.arr) // [18, 2, 3]
console.log(obj2.arr) // [18, 2, 3]
3、手写递归方法
// 定义一个深拷贝函数  接收目标target参数
function deepClone(target) {
    // 定义一个变量
    let result;
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
    // 如果是一个数组的话
        if (Array.isArray(target)) {
            result = []; // 将result赋值为一个数组,并且执行遍历
            for (let i in target) {
                // 递归克隆数组中的每一项
                result.push(deepClone(target[i]))
            }
         // 判断如果当前的值是null的话;直接赋值为null
        } else if(target===null) {
            result = null;
         // 判断如果当前的值是一个RegExp对象的话,直接赋值    
        } else if(target.constructor===RegExp){
            result = target;
        }else {
         // 否则是普通对象,直接for in循环,递归赋值对象的所有值
            result = {};
            for (let i in target) {
                result[i] = deepClone(target[i]);
            }
        }
     // 如果不是对象的话,就是基本数据类型,那么直接赋值
    } else {
        result = target;
    }
     // 返回最终结果
    return result;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Python中,可以使用copy模块中的deepcopy方法来实现列表的拷贝拷贝会创建一个完全独立的列表副本,无论多少层嵌套,得到的新列表都是和原来无关的。可以通过引入copy模块,并使用copy.deepcopy()来进行拷贝操作。例如: import copy old = [1,[1,2,3],3] new = copy.deepcopy(old) 在上述代码中,old是原始列表,new是拷贝得到的新列表。无论对new进行任何修改,都不会影响到old的值。这种方法是最安全、最清爽、最有效的拷贝方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [浅析Python中list的复制及拷贝拷贝](https://download.csdn.net/download/weixin_38643269/12867045)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Python中列表List的复制(直接复制、拷贝拷贝)](https://blog.csdn.net/weixin_49899130/article/details/129380610)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Echo___Echo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值