深拷贝浅拷贝有什么区别?怎么实现深拷贝?

news/2024/11/23 23:16:14/

目录

    • 一、浅拷贝
    • 二、深拷贝
    • 三、两者区别?

一、浅拷贝

浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝。
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址

在JavaScript中,存在浅拷贝的现象有:

  • Object.assign

    var obj = {age: 18,nature: ['smart', 'good'],names: {name1: 'fx',name2: 'xka'},love: function () {console.log('fx is a great girl')}}var newObj = Object.assign({}, obj);console.log(newObj);
    
  • Array.prototype.slice(),Array.prototype.concat()

    const fxArr = ["One", "Two", "Three"]
    const fxArrs = fxArr.slice(0)
    fxArrs[1] = "love";
    console.log(fxArr) // ["One", "Two", "Three"]
    console.log(fxArrs) // ["One", "love", "Three"]
    
    const fxArr = ["One", "Two", "Three"]
    const fxArrs = fxArr.concat()
    fxArrs[1] = "love";
    console.log(fxArr) // ["One", "Two", "Three"]
    console.log(fxArrs) // ["One", "love", "Three"]
    
  • 使用拓展运算符实现复制

    const fxArr = ["One", "Two", "Three"]
    const fxArrs = [...fxArr]
    fxArrs[1] = "love";
    console.log(fxArr) // ["One", "Two", "Three"]
    console.log(fxArrs) // ["One", "love", "Three"]
    

二、深拷贝

深拷贝就是开辟一个新的栈,两个对象的属性完全相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
常见的深拷贝方式有:

  • _.cloneDeep

    const _ = require('lodash');
    const obj1 = {a: 1,b: { f: { g: 1 } },c: [1, 2, 3]
    };
    const obj2 = _.cloneDeep(obj1);
    console.log(obj1.b.f === obj2.b.f);// false
    
  • Jquery.extend()

    const $ = require('jquery');
    const obj1 = {a: 1,b: { f: { g: 1 } },c: [1, 2, 3]
    };
    const obj2 = $.extend(true, {}, obj1);
    console.log(obj1.b.f === obj2.b.f); // false
    
  • JSON.stringify()

     const obj1 =  ["One", "Two", "Three"]const obj2=JSON.parse(JSON.stringify(obj1));console.log(obj2);
    

    但是这种方式存在弊端,会忽略undefined、symbol和函数

    const obj = {name: 'A',name1: undefined,name3: function() {},name4:  Symbol('A')
    }
    const obj2 = JSON.parse(JSON.stringify(obj));
    console.log(obj2); // {name: "A"}
    
  • 手写循环递归的方法

      function deepClone(obj, hash = new WeakMap()) {if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作if (obj instanceof Date) return new Date(obj);if (obj instanceof RegExp) return new RegExp(obj);// 可能是对象或者普通的值  如果是函数的话是不需要深拷贝if (typeof obj !== "object") return obj;// 是对象的话就要进行深拷贝if (hash.get(obj)) return hash.get(obj);let cloneObj = new obj.constructor();// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身hash.set(obj, cloneObj);for (let key in obj) {if (obj.hasOwnProperty(key)) {// 实现一个递归拷贝cloneObj[key] = deepClone(obj[key], hash);}}return cloneObj;}
    

三、两者区别?

在这里插入图片描述
从上图发现,浅拷贝和深拷贝都创建出一个新对象,但在复制对象属性的时候,行为就不一样。

  • 浅拷贝是只复制属性指向某个对象的指针,而不复制对象本身,新旧对象还是同一块内存,修改对象属性会影响原对象。
  • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改变原对象。

在这里插入图片描述


http://www.ppmy.cn/news/942498.html

相关文章

二、DDL-5.小结

一、数据库操作 1、查询 查询所有数据库 show databases; 查询目前所处数据库 select database(); 2、进入 进入某个数据库 use itcast; USE 数据库名; 3、创建 创建数据库 create database itcast; create database [if not exists] itcast; create database [if not …

手机流量单位的思考

关于手机流量的单位 今天突发奇想为什么手机流量的单位是GB、MB呢?这难道是计算机里面的那个GB、MB吗?于是查询了一下,在这里做个笔记。 手机流量是指手机上网产生的流量数据,用手机打开软件或进行互联网操作时,会和服…

物联网卡怎么查询流量?

随着时代的发展,物联网技术也被看做是互联网技术之后的又一历史性信息革命。在互联网时代我们可以通过WiFi、手机流量来看电视、最具、听音乐等,不过这些都是需要依赖于手机才能进行的。然而,随着物联网时代都是到来,我们有些事情…

ssm手机流量管理系统毕业设计(附源码、运行环境)

用户登录界面管理 流量查询管理 确认流量兑换管理 购买流量管理 免费赠送本源代码、数据库,请私信

android流量监控步骤_Android流量网络监控设计(超级实用版).doc

Android流量网络监控设计(超级实用版).doc 摘 要 伴随着Android智能移动设备的普及,其对网络系统和流量监控的要求越来越高,因而,让用户有能力实现对移动设备网络流量的实时监控和显示,同时进一步合理控制移动设备网络流量的使用状…

【Spark手机流量日志处理】使用SparkSQL按月统计流量使用量最多的用户

🚀 作者 :“大数据小禅” 🚀文章简介:本篇文章属于Spark系列文章,专栏将会记录从spark基础到进阶的内容 🚀 内容涉及到Spark的入门集群搭建,核心组件,RDD,算子的使用&…

android取流量统计,Android 统计应用流量的使用情况

Android 获取应用流量的使用情况有两种方法 TrafficStats NetworkStatsManager 是Android 6.0(API23)中新增加的类 这次我们使用的是第二种方法,记录一下实现过程 首先说明NetworkStatsManager能提供哪些功能 区分 Wifi 和手机网络的流量使用 查询指定应用的流量使用 查询指定…

Spark 实验:Scala手机号流量求和排序

一、实验描述 根据数据文件phone_data.txt按照如下需求: 1)统计每一个手机号耗费的总上行流量、下行流量、总流量 2)将统计结果按照手机归属地不同号段(手机号前3位)输出到不同文件中 3)根据需求1)产生的结果再次对总…