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 相关文章推荐
jQuery$命名冲突怎么办如何解决
Jan 16 Javascript
node.js中的console.trace方法使用说明
Dec 09 Javascript
简洁实用的BootStrap jQuery手风琴插件
Aug 31 Javascript
浅谈js继承的实现及公有、私有、静态方法的书写
Oct 28 Javascript
微信小程序 video详解及简单实例
Jan 16 Javascript
JS字符串统计操作示例【遍历,截取,输出,计算】
Mar 27 Javascript
微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)
Dec 08 Javascript
使用 vue-i18n 切换中英文效果
May 23 Javascript
微信小程序生成二维码的示例代码
Mar 29 Javascript
解决layui数据表格Date日期格式的回显Object的问题
Sep 19 Javascript
微信小程序纯文本实现@功能
Apr 08 Javascript
基于redis的小程序登录实现方法流程分析
May 25 Javascript
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
php利用腾讯ip分享计划获取地理位置示例分享
2014/01/20 PHP
Yii 访问 Gii(脚手架)时出现 403 错误
2018/06/06 PHP
java script编程起步(第三课)
2007/01/10 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
非jQuery实现照片散落桌子上,单击放大的LightBox效果
2014/11/28 Javascript
使用jQueryMobile实现滑动翻页效果的方法
2015/02/04 Javascript
JavaScript中判断两个字符串是否相等的方法
2015/07/07 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
2015/10/14 Javascript
Textarea输入字数限制实例(兼容iOS&安卓)
2017/07/06 Javascript
jqueryUI tab标签页代码分享
2017/10/09 jQuery
swiper自定义分页器使用方法详解
2020/09/14 Javascript
基于vue-ssr服务端渲染入门详解
2018/01/08 Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
2018/05/03 jQuery
vue通过video.js解决m3u8视频播放格式的方法
2019/07/30 Javascript
Layui table field初始化加载时进行隐藏的方法
2019/09/19 Javascript
vue使用screenfull插件实现全屏功能
2020/09/17 Javascript
JavaScript中跨域问题的深入理解
2021/03/04 Javascript
插入排序_Python与PHP的实现版(推荐)
2017/05/11 Python
Python使用min、max函数查找二维数据矩阵中最小、最大值的方法
2018/05/15 Python
python  Django中的apps.py的目的是什么
2018/10/15 Python
Django 中间键和上下文处理器的使用
2019/03/17 Python
将python安装信息加入注册表的示例
2019/11/20 Python
Python+PyQt5实现灭霸响指功能
2020/05/25 Python
使用Keras建立模型并训练等一系列操作方式
2020/07/02 Python
10行Python代码实现Web自动化管控的示例代码
2020/08/14 Python
利用HTML5中Geolocation获取地理位置调用Google Map API在Google Map上定位
2013/01/23 HTML / CSS
浅析HTML5中的 History 模式
2017/06/22 HTML / CSS
Spartoo比利时:欧洲时尚购物网站
2017/12/06 全球购物
澳大利亚现代波西米亚风格女装网站:Bohemian Traders
2018/04/16 全球购物
Haglöfs瑞典官方网站:haglofs火柴棍,欧洲顶级户外品牌
2018/10/18 全球购物
名人珠宝设计师:Melinda Maria Jewelry
2019/03/06 全球购物
俄罗斯首家面向中国消费者的一站式购物网站:Wruru
2020/05/08 全球购物
医学生实习自荐信
2013/10/01 职场文书
迟到检讨书400字
2014/01/13 职场文书
安全责任书怎么写
2014/07/28 职场文书
大学军训心得体会800字
2016/01/11 职场文书