javascript中存储对象都是存地址的。

浅拷贝:浅拷贝是都指向同一块内存区块,浅拷贝共用同一内存地址,你改值我也变。如果拷贝的对象里面的值是一个对象或者数组,它就是浅拷贝,拷贝的知识引用地址。 js的Object.assign,jquery的extend方法都是浅拷贝,一般的等号赋值也是浅拷贝 。

上面vue里面的两个写法也是浅拷贝,具体地址为 https://cn.vuejs.org/v2/guide/list.html

深拷贝:深拷贝则是另外开辟了一块区域,深拷贝是互不影响,你改值我也不变。angular里面的 angular.copy 是深拷贝。

下面实例也可以看出这一点:

  1. // 浅拷贝
  2. const a = {t: 1, p: 'gg'};
  3. const b = a;
  4. b.t = 3;
  5. console.log(a); // {t: 3, p: 'gg'}
  6. console.log(b); // {t: 3, p: 'gg'}
  1. //深拷贝
  2. const c = {t: 1, p: 'gg'};
  3. const d = deepCopy(c);
  4. d.t = 3;
  5. console.log(c); // {t: 1, p: 'gg'}
  6. console.log(d); // {t: 3, p: 'gg'}
  1. //浅拷贝 es6 扩展运算符
  2. let a = [,,,,];
  3. let b = a; // 相当于copy
  4. a.push();
  5. console.log(a); // [14, 12, 54, 33, 22, 44]
  6. console.log(b); // [14, 12, 54, 33, 22, 44]
  7.  
  8. //深拷贝
  9. let a = [,,,,];
  10. let b = [...a];
  11. a.push();
  12. console.log(a); // [14, 12, 54, 33, 22, 44]
  13. console.log(b); // [14, 12, 54, 33, 22]

可以明显看出,浅拷贝在改变其中一个值时,会导致其他也一起改变,而深拷贝不会。

Object.assign() ————深拷贝神器,这个方法就是用来拷贝一个对象的,通常做法就是Object.assign({}, sourceObject, { key1: value1,key2: value2})  {}表示目标对象,会定义成一个空的{},sourceObjec就是源对象

  1. // Cloning an object
  2. var obj = { a: 1 };
  3. var copy = Object.assign({}, obj);
  4. console.log(copy); // { a: 1 }
  1. // Merging objects
  2. var o1 = { a: 1 };
  3. var o2 = { b: 2 };
  4. var o3 = { c: 3 };
  5.  
  6. var obj = Object.assign(o1, o2, o3);
  7. console.log(obj); // { a: 1, b: 2, c: 3 }
  8. console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed.
  9. console.log(o2);//{b: 2} 源对象没有变
  10. console.log(o3);// {c: 3}

是不是很完美,又可以clone又可以merge。在我这种情况下,我觉得我的代码量又可以减少了,比如:

  1. const defaultOpt = {
  2. title: 'hello',
  3. name: 'oo',
  4. type: 'line'
  5. };
  6. // 原来可能需要这样
  7. const opt1 = deepCopy(a);
  8. opt1.title = 'opt1';
  9. opt1.type = 'bar';
  10. opt1.extra = 'extra'; // 额外增加配置
  11. // 现在只要这样
  12. const opt2 = Object.assign({}, a, {
  13. title: 'opt2',
  14. type: 'bar',
  15. extra: 'extra'
  16. });
  1. 注:它只对顶层属性做了赋值,完全没有继续做递归之类的把所有下一层的属性做深拷贝。意思就是是拷贝一层,没有拷贝多层。
  1. 一层
  2. {
  3. a: 1
  4. b: 2,
  5. }
  6.  
  7. 多层
  8. {
  9. a: 1
  10. b: 2,
  11. c: {
  12. d: 4,
  13. e: {
  14. f: 6,
  15. g: 7
  16. }
  17. }
  18. }
  1. 实现深拷贝,遍历key
  1. function deepClone(obj){
  2. //判断obj是否为数组,如果是,初始化数组[],否则初始化对象{}
  3. let dcObj = Array.isArray(obj)?[]:{};
  4. if(obj && typeof obj==="object"){
  5. //循环
  6. for(key in obj){
  7. //判断对象是否有key属性
  8. if(obj.hasOwnProperty(key)){
  9. //判断ojb子元素是否为对象,如果是,递归复制
  10. if(obj[key]&&typeof obj[key] ==="object"){
  11. dcObj[key] = deepClone(obj[key]);
  12. }else{
  13. //如果不是,简单复制
  14. dcObj[key] = obj[key];
  15. }
  16. }
  17. }
  18. }
  19. return dcObj;
  20. };
  21. let t1 = {
  22. "a": 1,
  23. "b": 2,
  24. "c": {
  25. "d": 4,
  26. "e": {
  27. "f": 6,
  28. "g": 7
  29. }
  30. }
  31. };
  32. let t2=deepClone(t1);
  33. t1.a=6;
  34. console.log(t1);
  35. /*
  36. {
  37. "a": 6,
  38. "b": 2,
  39. "c": {
  40. "d": 4,
  41. "e": {
  42. "f": 6,
  43. "g": 7
  44. }
  45. }
  46. }
  47. */
  48. console.log(t2); //t1深拷贝给t2, b属性的值还是为2,没有改变,所以是深拷贝
  49. /*
  50. {
  51. "a": 1,
  52. "b": 2,
  53. "c": {
  54. "d": 4,
  55. "e": {
  56. "f": 6,
  57. "g": 7
  58. }
  59. }
  60. }
  61. */

参考:https://www.jianshu.com/p/a66050673663

浅谈Javascript 浅拷贝和深拷贝的理解的更多相关文章

  1. 浅谈C#浅拷贝和深拷贝

    近来爱上一本书<编写高质量代码,改善C#程序的157个建议>,我想很多人都想编写高质量的代码,因为我们不仅仅是码农,更是一名程序员. 从今天开始,我将每天和大家分享这本书中的内容,并加上自 ...

  2. 浅谈java浅拷贝和深拷贝

    前言:深拷贝和浅拷贝的区别是什么? 浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之, 浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.深拷 ...

  3. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  4. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  5. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  6. 浅谈 JavaScript 编程语言的编码规范

    对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...

  7. 浅谈javascript的原型及原型链

    浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为 ...

  8. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  9. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

随机推荐

  1. wordpress不同分类调用不同的模板

    今天网友问ytkah:wordpress不同分类如何调用不同的模板.我们知道in_category() 函数可以通过分类别名或ID判断当前文章所属的分类,而且可以直接在循环(Loop)内部和外部使用. ...

  2. Java Excel 导入导出(二)

    本文主要叙述定制导入模板——利用XML解析技术,确定模板样式. 1.确定模板列 2.定义标题(合并单元格) 3.定义列名 4.定义数据区域单元格样式 引入jar包: 一.预期格式类型 二.XML模板格 ...

  3. 2019阿里JVM组实习面经

    面试质量非常高....非常高...高... 一面 自我介绍 看过hotspot哪些模块,模板解释器工作说一下,生成的native code放在哪,怎么处理safepoint的 说项目,实现了哪些字节码 ...

  4. apollo报:系统出错,请重试或联系系统负责人

    说明:基于 docker 搭建的 apollo,创建项目后一直报系统出错,请重试或联系系统负责人错误. 项目人员列表一直空白: 经排查是数据库配置参数不匹配,由于自己的虚拟机 ip 为 192.168 ...

  5. MongoDB 聚合查询报错

    1.Distinct聚合查询报错 db.users.distinct("uname") db.runCommand({"distinct":"user ...

  6. ESA2GJK1DH1K微信小程序篇: 测试微信小程序扫描Air202上面的二维码绑定设备,并通过MQTT控制设备

    前言 一,微信小程序篇小程序下载(该功能为小程序篇基础功能源码) 实现功能概要 微信小程序通过扫描GPRS上的二维码,绑定GPRS设备.然后使用小程序通过GPRS远程控制开发板上的继电器, 远程显示单 ...

  7. 【BigData】Java基础_冒泡排序

    1.实现需求 根据已经存在的数组,使用冒泡排序将数组中的元素排序后输出. 2.代码 package cn.test.logan.day02; /** * 冒泡排序在数组上的实现 * @author Q ...

  8. 提前体验让人"回归Windows怀抱"的Windows Terminal

    前言 在一年一度的微软开发者大会Build 2019登场的Windows Terminal饱受好评,大家对其也是充满了兴趣和热情,程序员的朋友圈都被微软发布的最新终端 windows Terminal ...

  9. js操作表格、table、

    js添加一行.删除一行 let str="<tr>" +"<td>"+a[1]+"</td>" +&qu ...

  10. ubuntu之路——day19.2 开源框架与迁移、CNN中的数据扩充

    开源框架与迁移 上面介绍了一些已经取得很好成绩的CNN框架,我们可以直接从GitHub上下载这些神经网络的结构和已经在ImageNet等数据集上训练好的权重超参数. 在应用于我们自己的数据时. 1.如 ...