首页 > 其他分享 >浅拷贝和深拷贝的区别

浅拷贝和深拷贝的区别

时间:2024-07-09 14:19:58浏览次数:13  
标签:target 区别 res Object 数据类型 拷贝 prototype

一、数据类型

在讨论深浅拷贝之前,我们先说说数据类型,因为深浅拷贝与数据类型有关。

数据类型分为基本数据类型(String、Number、Boolean、Null、Undefined、Symbol (es6引入的一种类型) )和引用数据类型(Object、Array、Function)。

基本数据类型特点:直接存储在栈中;

引用数据类型:它真实的数据是存储在堆内存中,栈中存储的只是指针,指向在堆中的实体地址。

二、浅拷贝、深拷贝

深浅拷贝只是针对Array与Object这样的引用数据类型。简单来说,浅拷贝只是拷贝了它在栈中存储的指针,它们指向的都是同一个堆内存地址,所以浅拷贝在某些情况会造成改变数据后导致别的另一份数据也同步被改变的情况;而深拷贝是直接将堆内存中存储的数据直接复制一份,不会有浅拷贝互相影响的问题。

三、浅拷贝的方法

1. Object.assign()

 

 

 

 从上面的例子我们发现,用Object.assign()实现的浅拷贝,当拷贝对象中的字段第一层的值为基础数据类型(如上面的a的值是个字符串,“a1”),那是不会被同步影响的;如果第一层的值还包含子对象(如上面b的值就是个对象,还包含了name字段),那就会被影响。所以如果被复制的object的每个字段第一层都是基础数据类型,那就是深拷贝。

2. Array.prototype.concat()

3. Array.prototype.slice()

2和3的方式效果与1一样,都是第一层的值为基础数据类型不会被同步影响,否则就会。

四、深拷贝的方法

1. JSON.parse(JSON.stringify())

将一个对象先转为json字符串,然后再转回来,这样可以实现深拷贝。

但是这个方法有个缺陷,可以实现对象或数组的深拷贝,但是不能处理函数,函数经过这样处理后会变成null。

 

 

 

 

 

所以比较推荐的方法是:

1. 递归的方法,遍历要克隆的每个字段,发现它的值是对象或数组后继续递归。

复制代码
function clone(target) {
    let res = undefined;
    if (Object.prototype.toString.call(target) === '[object Object]') {
        res = {};
    } else if (Object.prototype.toString.call(target) === '[object Array]') {
        res = [];
    } else {
        return target;
    }
    for (let key in target) {
        let value = target[key];
        if (Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]') {
            res[key] = clone(value);
        } else {
            res[key] = value;
        }
    }
    return res;
}
let a = [1,2,3,{ a: "a1", b: { name: "张三" } }]
let b = clone(a)
b[3].b.name = "我是b"
console.log(a,b)
复制代码

 

 

 

2. 比较推荐的方法,引用lodash依赖,使用里面的cloneDeep()方法

标签:target,区别,res,Object,数据类型,拷贝,prototype
From: https://www.cnblogs.com/itjeff/p/18291756

相关文章

  • 【转】你了解 localhost 与 127.0.0.1 的区别吗?
    引言在信息技术的世界里,localhost和127.0.0.1频繁出现在各种网络及软件开发的场景之中。它们似乎指向同一个意义——那就是你的本地机器。但仔细探究之下,你会发现它们之间其实存在着一些微妙的差异。今天,我们就来深究这两者之间的区别,并揭示它们在实际应用中的重要性。基本概......
  • @Autowired和@Resource有哪些区别
    一、注解的作用@Autowired和@Resource都是用来实现Bean的自动注入功能。二、@Autowired和@Resource的区别1、所属的包不同@Autowired是Spring的注解。@Resource是JSR-250的注解。IDEA有时候会在@Autowired注解上面提示Fieldinjectionisnotrecommended(字段注入是......
  • Franka 机器人中,标称末端执行器(Nominal End-Effector)与末端执行器(End-Effector)之
    在Franka机器人中,标称末端执行器(NominalEnd-Effector)与末端执行器(End-Effector)之间也存在一些区别。具体如下:定义:标称末端执行器(NominalEnd-Effector)是指Franka机器人在设计和制造时预设的、默认的末端执行器。末端执行器(End-Effector)则是指实际安装在机器......
  • 简述 JS 中对象的创建和拷贝
    在JavaScript中,对象是一种非常重要且灵活的数据结构,用于存储多个值(属性)和方法(函数)对象的创建和拷贝是日常开发中经常涉及的操作,对于业务逻辑的准确实现有着重要的作用本文将简要概括JavaScript中对象的创建和拷贝方式,都是一些非常基础的知识,大家看个乐就好~目录对象的作......
  • VCC、 VDD、VEE、VSS区别
    VCC、VDD、VEE、VSS区别版本一简单说来,可以这样理解:一、解释VCC:C=circuit表示电路的意思,即接入电路的电压;VDD:D=device表示器件的意思,即器件内部的工作电压;VSS:S=series表示公共连接的意思,通常指电路公共接地端电压;VEE:负电压供电;VPP:编程/擦除电压。二、说明1、对......
  • Vue2和Vue3区别的理解和学习1-API结构
    API结构Vue2采用选项式API,包括data、methods、mounted等,而Vue3则引入了组合式API,主要使用setup函数。这种变化使得代码组织更加模块化,更易于复用和维护。选项式API(OptionsAPI)包含多个选项的对象来描述组件的逻辑。选项所定义的属性都会暴露在函数内部的this上,......
  • Vue2和Vue3区别的理解和学习4-模板和语法
    Vue2和Vue3区别的理解和学习4-模板和语法组件定义//vue2exportdefault{data(){return{count:0}},methods:{increment(){this.count++}}}vue3---jsimport{ref}from'vue'expo......
  • 关于浅拷贝,深拷贝以及深拷贝的实现方法
    浅拷⻉:浅拷⻉会在堆上创建⼀个新的对象(区别于引⽤拷⻉的⼀点),不过,如果原对象内部的属性是引⽤类型的话,浅拷⻉会直接复制内部对象的引⽤地址,也就是说拷⻉对象和原对象共⽤同⼀个内部对象。深拷⻉:深拷⻉会完全复制整个对象,包括这个对象所包含的内部对象。我们知道在Java中......
  • 期刊论文中的结果、讨论、结论三者的区别是什么,他们三个在撰写的时候分别应该包含哪些
    问题描述:期刊论文中的结果、讨论、结论三者的区别是什么,他们三个在撰写的时候分别应该包含哪些内容?问题解答:在期刊论文中,结果(Results)、讨论(Discussion)和结论(Conclusion)是非常重要的部分,它们各自有明确的写作目的和内容要求。以下是对这三部分的详细解释及其区别:结果(Results......
  • 期刊论文一般包含引言、方法与材料、实验、结果、讨论、结论六个部分,或者将结果与讨论
    问题描述:期刊论文一般包含引言、方法与材料、实验、结果、讨论、结论六个部分,或者将结果与讨论合并就是五个部分。引言、方法与材料、实验、结果、讨论、结论六个部分在撰写时,分别包含哪些内容,这六个部分的区别是什么?问题解答:在撰写期刊论文时,通常包括引言(Introduction)、方......