今天来整理一下js中的深浅拷贝

深浅拷贝

简单来说,假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着A一起变了,说明这是浅拷贝,如果B没有变,那就是深拷贝。

看例题

//案例1var a1 = 1;var a2 = a1;console.log(a1); //1console.log(a2); //1a2 = 2; //修改 a2console.log(a1); //1console.log(a2); //2//案例2var o1 = { x: 1, y: 2 };var o2 = o1;console.log(o1); //{x: 1, y: 2}console.log(o2); //{x: 1, y: 2}o2.x = 2; //修改o2.xconsole.log(o1); //{x: 2, y: 2}console.log(o2); //{x: 2, y: 2}

按照常规思维,o1应该和a1一样,不会因为另外一个值的改变而改变,而这里的o1却随着o2的改变而改变了。同样是变量,为什么表现不一样呢?为了更好的理解js的深浅拷贝,我们先来理解一些js基本的概念。这里可以看看前面的文章(点击后面文字查看):javascript基础部分。看完了基础部分的知识,我们再回到上面的案例,案例1中的值(a1、a2)基本类型,案例2中的值(o1、o2)引用类型。案例2中的赋值就是典型的浅拷贝,并且深拷贝与浅拷贝的概念只存在于引用类型。

如何实现深拷贝

首先分别看看ArrayObject自有方法是否支持深拷贝:

  • 在通过数组和对象的自有方法来解决深拷贝之前,先附上之前整理的笔记(点击后面文字查看):js中数组的常用方法;js中对象的常用方法

Array

  • Array中可以使用slice()concat()方法来解决深拷贝的问题

//(1).slice()var arr1 = ["a", "b"];var arr2 = arr1.slice();console.log(arr1); // ["a", "b"]console.log(arr2); // ["a", "b"]arr2[0] = "c"; //修改arr2console.log(arr1); // ["a", "b"]console.log(arr2); // ["c", "b"]

//(2). concat()var arr1 = ["a", "b"];var arr2 = arr1.concat();console.log(arr1); // ["a", "b"]console.log(arr2); // ["a", "b"]arr2[0] = "c"; //修改arr2console.log(arr1); // ["a", "b"]console.log(arr2); // ["c", "b"]//通过上述两种方法,arr2的修改并没有影响到arr1,看来深拷贝的实现并没有那么难嘛。
  • slice()/concat()方法只能实现一维数组的深拷贝

//我们把arr1改成二维数组再来看看:var arr1 = ["a", "b", ["c", "d"]];var arr2 = arr1.concat();arr2[2][1] = 100;console.log(arr1); //['a', 'b', ['c', 100]]console.log(arr2); //['a', 'b', ['c', 100]]//这里arr2又改变了arr1
  • 还可以借用jquery库中的extend()方法来解决深拷贝的问题

var a = [0, 1, [2, 3], 4];var b = $.extend(true, [], a);a[0] = 1;a[2][0] = 1; //console.log(a); //[1,1,[1,3],4]console.log(b); //[0,1,[2,3],4]

Object

  • JSON.stringify()以及JSON.parse()来实现深拷贝

var obj = {  name: "yml",  age: 18,};var obj2 = JSON.parse(JSON.stringify(obj));obj.name = "NiceY";console.log(obj); // {name: "NiceY", age: 18}console.log(obj2); // {name: "yml", age: 18}// 使用JSON.stringify()以及JSON.parse()它是不可以拷贝 undefined,function,RegExp等等类型的
  • Object.assign(target, source)来实现深拷贝

var obj1 = {  a: 1,  b: 2,  c: ["a", "b", "c"],};var obj2 = Object.assign({}, obj1);obj2.b = 5;console.log(obj1.b); // 2console.log(obj2.b); // 5obj2.c[1] = 5;console.log(obj1.c); // ["a", 5, "c"]console.log(obj2.c); // ["a", 5, "c"]

//可以assign对于一层对象来说是没有任何问题的,但是如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题
  • 利用对象的深拷贝实现原理

//定义一个新的对象,遍历源对象的属性并赋给新对象的属性var obj = {  name: "yml",  age: 18,};var obj2 = new Object();obj2.name = obj.name;obj2.age = obj.age;

obj2.name = "NiceY";console.log(obj); //Object {name: "yml", age: 18}console.log(obj2); //Object {name: "NiceY", age: 18}

理解了以上的基本思想,我们就可以自己封装一个方法deep来实现对象的深拷贝,代码如下:

var Animal = {  name: "Ani",  color: ["red", "blue"],  child: {    age: 18,  },  say: function () {    console.log("I am", this.name, "color:", this.color);  },};function deep(dest, obj) {  var o = dest;  for (var key in obj) {    if (typeof obj[key] === "object") { //判断是不是对象      o[key] = obj[key].constructor === Array ? [] : {};      deep(o[key], obj[key]);    } else {      o[key] = obj[key];    }  }  return o;}deep(Animal); //返回的对象与Animal一样

END

js深拷贝和浅拷贝对数组的影响_javaScript中的深拷贝和浅拷贝相关推荐

  1. js深拷贝和浅拷贝对数组的影响_javascript之浅拷贝与深拷贝

    好久没提笔写文章了,之前忙得喘不过气,过年回家也无心学习.年后回来后,调整好状态,准备把js基础重新过一遍. 正文从此开始: 之所以写这篇文章是因为Leader最近在面试,回来和我们数落了一通,问一个 ...

  2. js深拷贝和浅拷贝对数组的影响_浅拷贝与深拷贝(JavaScript)

    一.预备知识 ECMAScript变量包含两种不同数据类型的值:基本数据类型和引用数据类型. 基本数据类型:名值存储在栈内存中: 引用数据类型:名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引 ...

  3. js深拷贝和浅拷贝对数组的影响_JS基础——深拷贝与浅拷贝

    浅拷贝 对象的浅拷贝 Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象. var target = { name:"rlxu&qu ...

  4. 前端的深拷贝和浅拷贝_javascript中的深拷贝和浅拷贝?

    感觉大家好像都没有正面回答题主的问题呢.题主问的是深复制和浅复制的区别,大家答的却都是如何实现深复制.我来答一发~ 首先深复制和浅复制只针对像 Object, Array 这样的复杂对象的.简单来说, ...

  5. JavaScript 数组拼接打印_JavaScript 中的“黑话”

    因为球是圆的,所以不论发生什么都有可能,对这点我是深信不疑的,但最近我总是在怀疑,JavaScript也是圆的! 什么是"黑话" 黑话,本指旧时江湖帮会人物的暗语.暗号,往往见于小 ...

  6. js中的深拷贝和浅拷贝区别

    js中的深拷贝和浅拷贝与值传递和引用传递有着些许的关联,都是根据堆栈中数据的储存来传递数据. 下面主要说一下我对深拷贝和浅拷贝的理解: 简单举个例子来说明:当我们声明一个a变量并且赋值,并且让b等于a ...

  7. 详细讲解js中的深拷贝与浅拷贝

    1 概述 深拷贝与浅拷贝在其它语言中也经常被提及到,在实际项目开发过程中也常常需要区分当前使用的到底是深拷贝还是浅拷贝,有时候在该使用深拷贝的地方,我们使用了浅拷贝,会导致深藏不露的bug. 2 数据 ...

  8. java数组深拷贝和浅拷贝_java中的深拷贝与浅拷贝(值类型 vs 引用类型)

    对象赋值 赋值是日常编程过程中最常见的操作,最简单的比如: Student codeSheep = new Student(); Student codePig = codeSheep; 严格来说,这 ...

  9. 【JavaScript】23_浅拷贝和深拷贝 + 对象的复制 + 数组的常用方法

    7.浅拷贝和深拷贝 浅拷贝(shallow copy) 通常对对象的拷贝都是浅拷贝 浅拷贝顾名思义,只对对象的浅层进行复制(只复制一层) 如果对象中存储的数据是原始值,那么拷贝的深浅是不重要 浅拷贝只 ...

最新文章

  1. 二分图专题系列各大知识点总结(匈牙利,染色法,最大独立集,最小点覆盖,最小路径覆盖)
  2. TCP长连接与短链接
  3. python嵌入式系统开发_Python在开发实时嵌入式系统中的作用
  4. 同济大学计算机直博,放弃直博浙江大学,选择保研同济大学!理性的他,做出这样的选择...
  5. SQL中常用的的时间跟日期函数
  6. java.net.ConnectException: Connection refused: no further information
  7. sas 检测到开型代码语句的递归_对于标准答案的递归很多人都看不懂,其实就是一个深度优先的遍历。我写了段伪代码,将递归步骤还原并注释了一下,供大家参考,希望大家有所收获。...
  8. 鹅厂算法大神干货实录,初赛通关“秘籍”还不赶快来GET!
  9. jQuery 学习笔记 事件委派
  10. NYOJ--60谁获得了最高奖学金
  11. linux 使cpu使用率升高_linux性能优化
  12. [openssl]centos version ‘libcrypto.so.10‘ not found
  13. redis 默认过期策略_redis 过期策略
  14. 如何通过百度翻译实现整站网页翻译
  15. 程序员这口饭,职业规划解决方案---程序员职业规划(二)
  16. SpringCLoud实战微服务之——微服务简介以及入门使用
  17. VS2010向工具箱中添加控件解决 Microsoft Communications Control,未能实例化 设计时授权
  18. [最大生成树Kruskal/倍增LCA] 火车运输 洛谷P1967
  19. Hadoop项目结构及其主要作用
  20. 户外广告的速度与激情

热门文章

  1. python爬虫案例——百度贴吧数据采集
  2. [转]oracle分页用两层循环还是三层循环?
  3. BZOJ1075 : [SCOI2007]最优驾车drive
  4. EXT.NET高效开发(二)——封装函数
  5. [转载] python 遍历字符串 字符_python 遍历字符串(含汉字)实例详解
  6. [转载] Python3入门精通基础教程(合集)
  7. [转载] Python正则表达式(含正则表达式速查表)
  8. Maven的下载、安装和配置
  9. 栈的应用(进制转换)
  10. centos7卸载旧jdk安装新jdk1.8