栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

浅拷贝与深拷贝

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅拷贝与深拷贝

首先我们要知道,js有两大类数据类型:

1.值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol

2.引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。


由于值类型数据较简单,所以创建时候直接储存在栈内存中,在拷贝的时候,会新生成一份储存在栈中,两者互不影响。

而引用数据类型,由于数据结构较复杂,所以创建时候一般都是储存在堆内存中,然后会在栈中生成一份引用(里面保存的是该引用类型在堆内存中的地址,类似c语言的指针)。在拷贝的时候,不会重新在堆内存中生成一份数据,而是直接在栈内存中新生成一份引用指向原本的那个堆内存地址。所以浅拷贝的话,只是拷贝了一份地址,指向了同一个对象,并没有新生成一个对象。


如果我们想要得到原对象的一份真正的独立的复制体,我们就需要对其进行手动深拷贝,即遍历该对象的所有属性,并将其添加到那个复制体对象上面去。

这时候我们会遇到一个问题,如果对象上面的属性是另一个对象,这时候如果我们进行普通普通拷贝,就会遇到和上面同样的问题,所以我们需要对这个手动的深拷贝函数进行循环调用。


function deepClone(obj = {}) {
    if (typeof obj != 'object' || obj == null) {
        //如果传入的obj不是一个对象,那么就不需要进行深拷贝,值类型直接赋值就可以了
        return obj
    }
    let newObj

    //判断obj是数组还是对象,以确认newObj的类型
    obj instanceof Object ? newObj = {} : newObj = []

    //用for in 遍历obj的属性
    for(let index in obj){
        //只拷贝对象本身拥有的属性,不拷贝原型链上面的属性
        if(obj.hasOwnProperty(index)){
            //循环调用赋值,因为有可能碰到obj的某个属性同样也是一个对象的情况
            newObj[index]=deepClone(obj[index])
        } 
    }
    return newObj
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/869399.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号