我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么解决JavaScript的深浅拷贝

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么解决JavaScript的深浅拷贝

这篇文章主要讲解了“怎么解决JavaScript的深浅拷贝”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决JavaScript的深浅拷贝”吧!

正文

从一则故事讲起,昨天因为医院开不出药,我拿上药取小区药店去买药,进门之后我问老板有没有这个药,老板转身进去一个小屋子拿了一盒药,果不其然确实有,药的名字和毫克一摸一样,但是盒子的样子和厂商不一样,我问老板:“这两个药是一种药吗,盒子不一样啊,药的成分是一样的吗?”老板说当然一样啊,这个就和你去买猪肉一样,同样是猪身上的肉,只不过是你去这个超市和去其他超市买场地一样而已。最后为了安全起见,我还是没有买那个药。

"拷贝"分为浅拷贝和深拷贝。它是针对对象来说的,如果不是对象一切免谈。这里的对象可以理解为我拿的那盒药,浅拷贝可以理解为老板拿出来的那盒药,虽然药的名字和毫克一样,然后里面的我们不知道是否真的一样,可能一样可能不一样。深拷贝可以理解为我买到了一摸一样的药,一层一层的药名,毫克,厂商,成分都一样。

总结:

  • 浅拷贝就是针对对象的属性依次进行复制,只复制一层,不会递归到个属性复制,会产生引用问题即内存地址是指的同一地址。简单来说就是拷贝之后和原对象有关

  • 深拷贝就是针对对象的各属性递归复制到新的对象上,内存地址不会指向同一地址。简单来说就是拷贝之后和元对象无关

下面看一个浅拷贝的例子:

let school={'name':"W3Cschool"};let my = {age:{count:18},name:"W3Cschool编程网"};let all = {...school,...my};my.age.count=100;console.log(all);console.log(my);

结果:

{ age: { count: 100 }, name: 'W3Cschool编程网' }{ age: { count: 100 }, name: 'W3Cschool编程网' }

结论是:浅拷贝修改拷贝之后的对象上的属性会把原对象身上的属性同时修改掉。

下面再看一个深拷贝的例子:

const _ = require("loadsh")let my = {age:{count:18},name:"W3Cschool编程网"};let all = _.cloneDeep(my);all.age.count =100;console.log(my);console.log(all);

结果:

{ age: { count: 18 }, name: 'W3Cschool编程网' }{ age: { count: 100 }, name: 'W3Cschool编程网' }

结论是:深拷贝修改拷贝之后的对象上的属性不会把原对象身上的属性同时修改掉。

拷贝的方法

数组方法:slice和concat

  • slice

let arr = [1,2,3,4];let arr2 = arr.slice(0)arr2[2]=5;console.log(arr);  //[ 1, 2, 3, 4 ]console.log(arr2); //[ 1, 2, 5, 4 ]

当数组里是不是对象的时候从结果上看是深拷贝,在看下面例子

let arr = [{1:1,2:2}];let arr2 = arr.slice(0)arr2[2]=5;console.log(arr);  //[ { '1': 1 }, { '2': 5 } ]console.log(arr2); //[ { '1': 1 }, { '2': 5 } ]

当数组里是对象的时候就变成了浅拷贝

  • concat

let arr = [1,2,3,4];let arr2 = [].concat(arr);arr2[2]=5;console.log(arr); //[ 1, 2, 3, 4 ]  ✔console.log(arr2); //[ 1, 2, 5, 4 ]

当数组里不是对象的时候从结果上看是深拷贝,在看下面例子

let arr = [{1:1},{2:2}];let arr2 = arr.cancat(0)arr2[1][2]=5;console.log(arr);  //[ { '1': 1 }, { '2': 5 } ]  ❌变成了引用console.log(arr2); //[ { '1': 1 }, { '2': 5 } ]

当数组里是对象的时候就变成了浅拷贝

总结:只有当数组是一维数组而且不包含对象的时候才是深拷贝

(推荐教程:JavaScript教程)

Object.assgin()

let a= {a:1,b:2};let b= Object.assign({},a);a.a=3;console.log(a)  //{a: 3, b: 2}console.log(b)  //{a: 1, b: 2}  ✔let a= {a:1,b:{c:2}};let b= Object.assign({},a);a.b.c=3;console.log(a)  //{a: 1, b: {c:3}}console.log(b)  //{a: 1, b: {c:3}}   ❌变成了引用

总结:Object.assgin如果涉及到嵌套多个对象的话就变成了引用 解决方法:使用JSON.stringify()先转化成字符串,再通过JSON.parse()转化成对象

  • 3.JSON.parse(JSON.stringify())

let a= {a:1,b:{c:2}};let b= JSON.parse(JSON.stringify(a))a.b.c=3;console.log(a)  //{a: 1, b: {c:3}}console.log(b)  //{a: 1, b: {c:2}}   ✔let school={'name':"W3Cschool编程网",fn:function(){}};let my = {age:{count:18},name:"W3Cschool编程网"};let all=JSON.parse(JSON.stringify({...school,...my}))console.log(all);  //{'name':"W3Cschool编程网",age:{count:18}}; //❌把fn给丢了

总结: JSON.parse(JSON.stringify()) 这个方法有一定的局限性,会丢失 fn 。

  • 手写深拷贝

let deepClone=(obj)=>{    if(obj==undefined) return obj;  //undefined == null    if(obj instanceof RegExp) return new RegExp(obj);    if(obj instanceof Date) return new Date(obj);    if(typeof obj!=="object") return obj;    let newObj = new obj.constructor;    for(let key in obj){        if(obj.hasOwnProperty(key)){            newObj[key] = deepClone(obj[key])        }    }    return newObj;}let obj1 = {name:{age:"10"}}let n = deepClone(obj1)obj1.name.age = "231"console.log(n);  //{name:{age:"10"}}  ✔let obj = { name:"W3Cschool编程网" }obj.aaa=objlet n = deepClone(obj1)console.log(n);  //死循环了  ❌

解决这个问题可以使用WeakMap

let deepClone=(obj,hash=new WeakMap())=>{    if(obj==undefined) return obj;  //undefined == null    if(obj instanceof RegExp) return new RegExp(obj);    if(obj instanceof Date) return new Date(obj);    if(typeof obj!=="object") return obj;    if(hash.has(obj)) return hash.get(obj);    let newObj = new obj.constructor;    hash.set(obj,newObj);    for(let key in obj){        if(obj.hasOwnProperty(key)){            newObj[key] = deepClone(obj[key],hash)        }    }    return newObj;}
  • lodash的cloneDeep

<br> 源码地址:https://github.com/lodash/lodash/blob/86a852fe763935bb64c12589df5391fd7d3bb14d/.internal/baseClone.js<br> ```
  • vue-router源码中的克隆方法

function clone (value) {  if (Array.isArray(value)) {    return value.map(clone)  } else if (value && typeof value === 'object') {    const res = {}    for (const key in value) {      res[key] = clone(value[key])    }    return res  } else {    return value  }}let arr = [{1:1},{2:2},function(){}];let arr2 = clone(arr)arr2[1][2]=5;console.log(arr)  //[ { '1': 1 }, { '2': 2 }, [Function (anonymous)] ]   ✔ 深拷贝console.log(arr2); //[ { '1': 1 }, { '2': 5 }, [Function (anonymous)] ]function extend (a, b) {  for (const key in b) {    a[key] = b[key]  }  return a}let b={a:1,b:{c:2}};let a= extend({},b);a.b.c=5;console.log(a);  //{ a: 1, b: { c: 5 } }console.log(b);  //{ a: 1, b: { c: 5 } }   浅拷贝

感谢各位的阅读,以上就是“怎么解决JavaScript的深浅拷贝”的内容了,经过本文的学习后,相信大家对怎么解决JavaScript的深浅拷贝这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么解决JavaScript的深浅拷贝

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么解决JavaScript的深浅拷贝

这篇文章主要讲解了“怎么解决JavaScript的深浅拷贝”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决JavaScript的深浅拷贝”吧!正文从一则故事讲起,昨天因为医院开不出药,
2023-06-27

JavaScript深拷贝与浅拷贝实现详解

深拷贝和浅拷贝是面试中经常出现的,主要考察对基本类型和引用类型的理解深度,这篇文章主要给大家介绍了关于js深拷贝和浅拷贝的相关资料,需要的朋友可以参考下
2022-11-13

JavaScript深拷贝与浅拷贝是什么

这篇文章主要介绍了JavaScript深拷贝与浅拷贝是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1 浅拷贝概念深拷贝和浅拷贝是只针对Object和Array这样的引用
2023-06-29

如何理解JavaScript中的浅拷贝与深拷贝

本篇文章给大家分享的是有关如何理解JavaScript中的浅拷贝与深拷贝,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 浅拷贝在使用JavaScript对数组进行操作的时候,如
2023-06-16

怎么理解python指针拷贝,浅拷贝和深拷贝

本篇内容主要讲解“怎么理解python指针拷贝,浅拷贝和深拷贝”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解python指针拷贝,浅拷贝和深拷贝”吧!首先对于不可变类型int,strin
2023-06-02

JavaScript深浅拷贝的介绍

本篇内容介绍了“JavaScript深浅拷贝的介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!了解拷贝背后的过程,避免不必要的错误,Js专
2023-06-07

Java中浅拷贝和深拷贝该怎么理解

这篇文章给大家介绍Java中浅拷贝和深拷贝该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java浅拷贝深拷贝浅拷贝和深拷贝涉及到了Object类中的clone()方法实现浅拷贝浅拷贝的实现需要类重写clone
2023-06-21

Java的深拷贝与浅拷贝怎么使用

在Java中,对象的拷贝分为浅拷贝和深拷贝两种方式。浅拷贝是指创建一个新的对象,然后将原对象的非静态字段值复制到新对象中。新对象和原对象的引用类型字段将指向相同的对象。可以通过实现`Cloneable`接口并重写`clone()`方法来实现
2023-08-18

深入理解python中的浅拷贝和深拷贝

在讲什么是深浅拷贝之前,我们先来看这样一个现象:a = ['scolia', 123, [], ] b = a[:] b[2].append(666) print a print b为什么我只对b进行修改,却影响到了a呢?看过我在之前的文章
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录