JS的深浅复制详细


Posted in Javascript onOctober 16, 2021

1、浅复制的意思

浅复制是仅仅对数据存放在栈内的引用的复制,没有复制引用指向堆内的内容。多个数据的浅复制,这复制多个引用,这多个引用共同指向堆内的同一个内容。当一个浅复制数据做出修改,即堆内的引用指向的内容发生修改,这时,其他通过引用指向这里的数据也会随着改变。

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = obj;
objA.a = 'a';

console.log(obj.a);  // 'a'
console.log(objA.a);  // 'a'

2、深复制的意思

深复制是指连同堆的内容一块复制,生成一个新的对象。多个深复制将是多个不同的对象,也就有不同的引用,也就指向不同的堆内容。

3、使用深复制的原由

在平常开发中,有时会有数据的传递与接收,当拿到传过来的数据后,难免需要对数据进行加工和改造,为了不破坏原有数据结构,这时就可以使用深复制拷贝数据,然后处理生成的新的数据。深复制也可以防止修改多个引用后引用混乱的问题,减少BUG的产生机会。

4、可实现深复制的几种方法

实现方式一:JSON的序列化与反序列化

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = JSON.parse(JSON.stringify(obj));//JSON的序列化与反序列化
objA.a = 'a';

console.log(obj.a);  // 1
console.log(objA.a);  // 'a'

虽然JSON的序列化与反序列化可以实现深复制,但有几个缺点需要注意:

  • date日期对象被转成日期日期字符串
  • 没法访问到原型
  • 复制不了undefined的属性
  • NAN和无穷被转为NULL
let d1 = new Date();
let obj = {
    d1,
    d2: undefined,
    d3:NaN
}
let objD = JSON.parse(JSON.stringify(obj));
console.log(obj) 
console.log(objD)

实现方式二:Object.assign()

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = Object.assign(obj);
objA.a = 'a';

console.log(obj.a);  // 1
console.log(objA.a);  // 'a'

虽然Object.assign()可以实现深复制,但对于更深层次的对象引用也是仅仅浅复制。

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = Object.assign(obj);
objA.c.c1 = 'c1'; //Object.assign()仅仅是一层深复制。

console.log(obj.c.c1);  // 'c1'
console.log(objA.c.c1);  // 'c1'

实现方式三:扩展运算符

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = {...obj};;
objA.a = 'a';

console.log(obj.a);  // 1
console.log(objA.a);  // 'a'

虽然扩展运算符" "可以实现深复制,但对于更深层次的对象引用也是仅仅浅复制。

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = {...obj};
objA.c.c1 = 'c1'; //扩展运算符"..."同Object.assign()一样,仅仅是一层深复制,不能多层深复制。

console.log(obj.c.c1);  // 'c1'
console.log(objA.c.c1);  // 'c1'

实现方式四:使用递归

想要实现深复制,且实现多层深复制则可以使用递归循环复制。

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

const ReCopy = function (paramter) {
        let target = null;
        let isObject = paramter.constructor === Object;
        let isArray = paramter.constructor === Array;
        if (isObject || isArray) {
            target = Array.isArray(paramter) ? [] : {};
            for (let i in paramter) {
                target[i] = ReCopy(paramter[i]);
            }
        } else {
            target = paramter;
        }
        return target;
    }

let objA = ReCopy(obj);
objA.c.c1 = 'c1';

console.log(obj.c.c1);  // 10
console.log(objA.c.c1);  // 'c1'

5、ladash深拷贝

lodash深复制是更专业的深复制方式。

安装lodash

先初始化,生成package.json文件,然后使用一下命令安装。

npm i -S lodash

引入lodash

var _ = require('lodash');

使用lodash

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = _.cloneDeep(obj);
objA.c.c1 = 'c1'; 

console.log(obj.c.c1);  // 10
console.log(objA.c.c1);  // 'c1'

到此这篇关于JS的深浅复制详细的文章就介绍到这了,更多相关JS的深浅复制内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
弹出广告特效代码(一个IP只弹出一次)
May 11 Javascript
用javascript做拖动布局的思路
May 31 Javascript
javascript 子窗体父窗体相互传值方法
May 31 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
Aug 01 Javascript
jQuery UI AutoComplete 自动完成使用小记
Aug 21 Javascript
基于jquery的多彩百分比 动态进度条 投票效果显示效果实现代码
Aug 28 Javascript
jQuery LigerUI 使用教程入门篇
Jan 18 Javascript
浅析JQuery中的html(),text(),val()区别
Sep 01 Javascript
JavaScript图片轮播代码分享
Jul 31 Javascript
jQuery基于cookie实现的购物车实例分析
Dec 24 Javascript
微信小程序 自定义弹窗实现过程(附代码)
Dec 05 Javascript
vue使用echarts图表自适应的几种解决方案
Dec 04 Vue.js
JS 基本概念详细介绍
Oct 16 #Javascript
AJAX实现指定部分页面刷新效果
AJAX实现省市县三级联动效果
Oct 16 #Javascript
简单聊聊Vue中的计算属性和属性侦听
Oct 05 #Vue.js
JS中如何优雅的使用async await详解
Oct 05 #Javascript
js中Object.create实例用法详解
Oct 05 #Javascript
TypeScript中条件类型精读与实践记录
Oct 05 #Javascript
You might like
真正面向对象编程:PHP5.01发布
2006/10/09 PHP
php判断访问IP的方法
2015/06/19 PHP
php实现给二维数组中所有一维数组添加值的方法
2017/02/04 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
2020/04/04 PHP
基于php伪静态的实现方法解析
2020/07/31 PHP
javascript的offset、client、scroll使用方法详解
2012/12/25 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
在JavaScript应用中实现延迟加载的方法
2015/06/25 Javascript
用JavaScript判断CSS浏览器类型前缀的两种方法
2015/10/08 Javascript
jQuery实现的瀑布流加载效果示例
2016/09/13 Javascript
浅谈vue父子组件怎么传值
2018/07/21 Javascript
Vue配合iView实现省市二级联动的示例代码
2018/07/27 Javascript
angular6.x中ngTemplateOutlet指令的使用示例
2018/08/09 Javascript
详解在React项目中安装并使用Less(用法总结)
2019/03/18 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
2019/09/26 Javascript
vue+vant使用图片预览功能ImagePreview的问题解决
2020/04/10 Javascript
vue中使用router全局守卫实现页面拦截的示例
2020/10/23 Javascript
[02:51]DOTA2 Supermajor小组分组对阵抽签仪式
2018/06/01 DOTA
Python爬虫包 BeautifulSoup  递归抓取实例详解
2017/01/28 Python
Python wxpython模块响应鼠标拖动事件操作示例
2018/08/23 Python
在自动化中用python实现键盘操作的方法详解
2019/07/19 Python
python 6种方法实现单例模式
2020/12/15 Python
纯css实现照片墙3D效果的示例代码
2017/11/13 HTML / CSS
在HTML5 Canvas中放入图片和保存为图片的方法
2014/05/03 HTML / CSS
加拿大鞋子连锁店:Town Shoes
2016/09/26 全球购物
机械制造与自动化应届生求职信
2013/11/16 职场文书
我爱我家教学反思
2014/05/01 职场文书
财务人员担保书
2014/05/13 职场文书
网吧七夕活动策划方案
2014/08/31 职场文书
领导班子群众路线与四风问题对照检查材料思想汇报
2014/10/11 职场文书
收入及婚姻状况证明
2014/11/20 职场文书
活动宣传稿范文
2015/07/23 职场文书
竞聘书的秘诀
2019/04/02 职场文书
七年级话题作文之执着
2019/11/19 职场文书
html+css实现赛博朋克风格按钮
2021/05/26 HTML / CSS
使用python+pygame开发消消乐游戏附完整源码
2021/06/10 Python