深拷贝学习笔记

在开发过程中,我碰到了一个问题,让我找了好久问题在哪里,最后我发现是最开始赋值的时候没有深拷贝值,导致了原本值被覆盖污染,这里和大家分享下我的解决方法

var i = 5;

var j = i;

j=1;

console.log(i);//5

console.log(j);//1

  

我们正常赋值的逻辑是像上面一样,复制一份下来,然后对复制的那一份进行操作,这样的逻辑是对的,但是这样的拷贝默认是浅拷贝,当出现以下情况时,这种写法就会出问题

var i = {

        value:5

};

var j = i;

j.value=1;

console.log(i.value);//1

console.log(j.value);//1

  

是不是觉得很奇怪,我在网上找了一下为什么,是有关浅拷贝和深拷贝的知识:

(浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针,出现深浅拷贝的情况是当对象为Object或Array时才会出现。)

我分享下我的三种种解决方法:

第一种,使用JSON.parse(JSON.stringify())

let arr = [1, 3, {

    username: ' kobe'

}];

let arr4 = JSON.parse(JSON.stringify(arr));

arr4[2].username = 'duncan';

console.log(arr, arr4)

  

原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

第二种:Object.assign()

var obj = { a: {a: "kobe", b: 39} };

var initalObj = Object.assign({}, obj);

initalObj.a.a = "wade";

console.log(obj.a.a); //wade

  

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

第三种:手写递归方法

递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

function getType(obj) {
  //tostring会返回对应不同的标签的构造函数
  var toString = Object.prototype.toString;
  var map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  if (obj instanceof Element) {
    return 'element';
  }
  return map[toString.call(obj)];
}

//深拷贝
 function deepClone(data) {
  var type = getType(data);
  var obj;
  if (type === 'array') {
    obj = [];
  } else if (type === 'object') {
    obj = {};
  } else {
  //不再具有下一层次
    return data;
  }
  if (type === 'array') {
    for (var i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]));
    }
  } else if (type === 'object') {
    for (var key in data) {
      obj[key] = deepClone(data[key]);
    }
  }
  return obj;
}

如果大家有其他方法,也欢迎在下面分享ヽ( ̄▽ ̄)ノ

(0)

相关推荐

  • 遍历数组,对象和JSON

    遍历数组 var arr2 = [3,4,5,6,7,8]; //第一种方法 for(var i =0;i<arr.length;i++){ console.log(arr2[i]); } // ...

  • JavaScript之浅谈深拷贝与浅拷贝

    这一章我们聊一下js中深拷贝与浅拷贝 深拷贝和浅拷贝的区别? 1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用 2.深拷贝: 创建一个新的对象和数组,将原对 ...

  • javascript 一 03 数据类型的转换

    强制转换 Number() String() Boolean() Number() 使用 Number 函数,可以将任意类型的值转化成数值. Number(324); // 324 Number(&q ...

  • 前端【JS】,深拷贝与浅拷贝的区别及详解!

    我是前端小白一枚,为了巩固知识和增强记忆,开始整理相关的知识,方便以后复习和面试的时候看看. OK,让我们进入正题~ 先说说浅拷贝和深拷贝的理解吧,个人是这样理解的: 两个对象A.B, A有数据B为空 ...

  • 一则公报案例学习笔记:对修改股东出资期限应否适用资本多数决规则的思考|审判研究

    一.问题的提出 2021年第3期<最高人民法院公报案例>刊登了鸿大(上海)投资管理有限公司与姚锦城公司决议纠纷上诉案,裁判要旨为:"公司股东滥用控股地位,以多数决方式通过修改出资 ...

  • JAVA多线程学习笔记整理

    多线程: 三种创建方法 继承Thread类,以线程运行内容重写run方法,创建Thread对象并用start方法启动该线程. (匿名内部类) (Lambda表达式) 实现Runable接口,以线程运行 ...

  • 周哥学习笔记(2021.5.8)

    心理界限存在的意义,正是为了帮助人们控制情绪进入的量,不至于太过冷漠或太过投入,让我们保持一个合适的距离与外界互动. 人没有办法只通过吸收变得更美好和丰富,它必须通过大胆的碰撞和创造.如果不能保持足够 ...

  • 【学习笔记】控制角色移动的N种方法,但都离不开重复执行

    [学习笔记]控制角色移动的N种方法,但都离不开重复执行 今天我们讲一下控制角色移动的多种方法,因为缺少操作实例,希望课下同学们结合例子好好练习. 首先,我们说一下控制角色移动的多种方法.最比较常见的就 ...

  • 胡希恕伤寒论学习笔记——42

    42.太阳病,外证未解,脉浮弱者,当以汗解,宜桂枝汤. 字面意思是说:太阳病,外证依然存在,脉是浮弱的,治疗上依然需要通过出汗的方法,这时应该用桂枝汤一类的方剂. "宜"字说明不是 ...

  • 量柱擒涨停 - 量柱战法学习笔记(2)

    四.倍量战术 1.倍量的理解 [形态特征]:与前一个交易日比较高出1倍或1倍以上,就是倍量(4倍以上为发烧柱) ; [本质特征]:体现主力强势态度,主动(倍量阳/阴)买/卖盘吸筹坚决; [位置性质]: ...

  • 胡希恕伤寒论学习笔记——43

    43.太阳病,下之微喘者,表未解故也,桂枝加厚朴杏子汤主之. 桂枝加厚朴杏子汤方 桂枝三两 芍药三两 厚朴二两(炙,去皮) 杏仁五十枚(去皮尖)甘草二两(炙) 生姜三两(切)大枣十二枚(掰) 上七味, ...

  • 学习笔记:信息技术

    学习笔记:信息技术

  • 安全学习笔记

    安全学习笔记