js中的深浅拷贝问题简析


Posted in Javascript onMay 10, 2019

前言

在开发过程中,偶尔会遇到这种场景,拿到一个数据后,你打算对它进行处理,但是你又希望拷贝一份副本出来,方便数据对比和以后恢复数据。

那么这就涉及到了 JS 中对数据的深浅拷贝问题,所谓深浅拷贝,浅拷贝的意思就是,你只是复制了对象数据的引用,并没有把内存里的值另外复制一份,那么深拷贝就是把值完整地复制一份新的值。

下面这篇文章就对js中的深浅拷贝进行了深入的讲解,下面话不多说了,来一起看看详细的介绍吧

问题描述:

因为在JavaScript中对象在赋值中存储的是对象的地址(指针),所以会造成对象类型在复制过程中只复制对象的地址,从而导致以下问题

var people = {
 name: "小明"
 }
var peoplea = people;
peoplea.name = "小白";
console.log(peoplea.name)//小白
console.log(people.name)//小白

我们本来期望只改变peoplea的name,现在连people的name都改变了。根据情况的不同,可使用深拷贝或浅拷贝来解决。

解决方法:

我们在实现深浅拷贝之前,我们先看一看深、浅拷贝、赋值这三种的区别:

1、赋值

改变新对象时不管第几层,老对象都会随着变化。

var people = {
 name: "小明",
 act: ["吃饭","睡觉"]
}
var people1 = people;//赋值
people1.name = "小红";
 people1.act[1] = "打游戏";
console.log(people.name);//小红
console.log(people.act);//["吃饭", "打游戏"]

2、浅拷贝

改变新对象第一层基本数据类型时,老对象不变。有子对象时,改变子对象,老对象会随着变化。

var people = {
  name: "小明",
  act: ["吃饭", "睡觉"]
}
var people1 = Object.assign({}, people);//浅拷贝
people1.name = "小红";
people1.act[1] = "打游戏";
console.log(people.name);//小明
console.log(people.act);// ["吃饭", "打游戏"]

3、深拷贝

不管改变新对象第几层,老对象都不会随之改变。

var people = {
  name: "小明",
  act: ["吃饭", "睡觉"]
}
var people1 = JSON.parse(JSON.stringify(people));//深拷贝
people1.name = "小红";
people1.act[1] = "打游戏";
console.log(people.name);//小明
console.log(people.act);// ["吃饭", "睡觉"]

总结一下就是:

第一层为基本数据类型 多于一层含有子对象
赋值 新老一起改变 新老一起改变
浅拷贝 新对象改变,老对象不变 新老一起改变
深拷贝 新对象改变,老对象不变 新对象改变,老对象不变

了解完了区别,下面介绍实现深浅拷贝的几个方法。

一、浅拷贝

1、Object.assign()

官方对这个函数的介绍是:Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。实际上就是会把属性中的简单数据类型直接复制,而对于对象属性,只会拷贝地址(指针),上边介绍区别时用的就是这个;

var people1 = Object.assign({}, people);

需要注意的是,如果对象没有子对象,Object.assign()实现的就是深拷贝。

2、展开运算符(ES6新增)

var people = {
  name: "小明",
  act: ["吃饭", "睡觉"]
}
var people1 = {...people};
people1.name = "小红";
people1.act[1] = "打游戏";
console.log(people.name);//小明
console.log(people.act);// ["吃饭", "打游戏"]

3、自己写

var people = {
  name: "小明",
  act: ["吃饭", "睡觉"]
 }
 var people1 = shallowCopy(people);
 people1.name = "小红";
 people1.act[1] = "打游戏";
 console.log(people.name);//小明
 console.log(people.act);// ["吃饭", "打游戏"]
 function shallowCopy(obj) {
  var res = {};
  for (var index in obj) {
  if (obj.hasOwnProperty(index)) {//不复制原型链上的属性
   res[index] = obj[index];
  }
  }
  return res;
 }

二、深拷贝

1、JSON.parse(JSON.stringify(obj))

上边介绍区别时用的就是这个:

var people1 = JSON.parse(JSON.stringify(people));//深拷贝

这个方法比较简便但也存在问题

1、不能复制对象中的函数。

2、会忽略对象中的undefind。

2、lodash函数

官方介绍是:lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库。官网是
www.lodashjs.com/ ,我推荐用其中的_.cloneDeep(value)方法。

ar objects = [{ "a": 1 }, { "b": 2 }];
 
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

还有自己去写一个递归,但是需要考虑的东西较多,不再赘述,也有用jq的$.extend()方法实现的,但是性能不好,这里提一下。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
Jan 15 Javascript
js函数的引用, 关于内存的开销
Sep 17 Javascript
JavaScript高级程序设计(第3版)学习笔记6 初识js对象
Oct 11 Javascript
js 延迟加载 改变JS的位置加快网页加载速度
Dec 11 Javascript
JS解决ie6下png透明的方法实例
Aug 02 Javascript
JavaScript Promise启示录
Aug 12 Javascript
JavaScript插件化开发教程(六)
Feb 01 Javascript
JavaScript实现Java中StringBuffer的方法
Feb 09 Javascript
JavaScript判断用户名和密码不能为空的实现代码
May 16 Javascript
使用Vue 实现滑动验证码功能
Jun 27 Javascript
Vue2.0实现简单分页及跳转效果
Jul 29 Javascript
原生Js 实现的简单无缝滚动轮播图的示例代码
May 10 Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
May 10 #Javascript
详解jQuery如何实现模糊搜索
May 10 #jQuery
JS匿名函数内部this指向问题详析
May 10 #Javascript
详解关于React-Router4.0跳转不置顶解决方案
May 10 #Javascript
Vue使用watch监听一个对象中的属性的实现方法
May 10 #Javascript
微信小程序获取用户信息并保存登录状态详解
May 10 #Javascript
jsonp实现百度下拉框功能的方法分析
May 10 #Javascript
You might like
哪吒敖丙传:新人物二哥敖乙出场 小敖丙奶气十足
2020/03/08 国漫
模拟xcopy的函数
2006/10/09 PHP
PHP多文件上传类实例
2015/03/07 PHP
php上传图片客户端和服务器端实现方法
2015/03/30 PHP
javascript操作文本框readOnly
2007/05/15 Javascript
js判断变量是否空值的代码
2008/10/26 Javascript
扩展JavaScript功能的正确方法(译文)
2012/04/12 Javascript
Javascript 遍历页面text控件详解
2014/01/06 Javascript
readonly和disabled属性的区别
2015/07/26 Javascript
解决angular的post请求后SpringMVC后台接收不到参数值问题的方法
2015/12/10 Javascript
jQuery实现验证年龄简单思路
2016/02/24 Javascript
JS定时器用法分析【时钟与菜单中的应用】
2016/12/21 Javascript
用原生js做单页应用
2017/01/17 Javascript
vue中实现左右联动的效果
2018/06/22 Javascript
express express-session的使用小结
2018/12/12 Javascript
vue视图不更新情况详解
2019/05/16 Javascript
js简单遍历获取对象中的属性值的方法示例
2019/06/19 Javascript
Vue + Element UI图片上传控件使用详解
2019/08/20 Javascript
vue 实现图片懒加载功能
2020/12/31 Vue.js
Python入门篇之函数
2014/10/20 Python
Python多进程并发(multiprocessing)用法实例详解
2015/06/02 Python
Python数据可视化正态分布简单分析及实现代码
2017/12/04 Python
详解PyTorch手写数字识别(MNIST数据集)
2019/08/16 Python
python标识符命名规范原理解析
2020/01/10 Python
国际鲜花速递专家:Floraqueen
2016/11/24 全球购物
美国眼镜在线零售商:Dualens
2019/12/07 全球购物
关于安全演讲稿
2014/05/09 职场文书
大学生找工作求职信
2014/07/09 职场文书
励志演讲稿800字
2014/08/21 职场文书
教学改革问题查摆整改措施
2014/09/27 职场文书
学校查摆问题整改措施
2014/09/28 职场文书
民间借贷借条范本
2015/05/25 职场文书
宾馆客房管理制度
2015/08/06 职场文书
幼儿园保教工作总结2015
2015/10/15 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
火锅店的开业营销方案范本!
2019/07/05 职场文书