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 Aajx访问WCF服务(GET、POST、PUT、DELETE)
Mar 16 Javascript
JavaScript栏目列表隐藏/显示简单实现
Apr 03 Javascript
更快的异步执行(setTimeout多浏览器)
Aug 12 Javascript
深入理解JavaScript编程中的同步与异步机制
Jun 24 Javascript
jQuery动态星级评分效果实现方法
Aug 06 Javascript
理解和运用JavaScript的闭包机制
Aug 13 Javascript
jquery ajax分页插件的简单实现
Jan 27 Javascript
angularjs $http调用接口的方式详解
Aug 13 Javascript
node.js实现微信开发之获取用户授权
Mar 18 Javascript
浅谈Vue的响应式原理
May 30 Javascript
JS中封装axios来管控api的2种方式
Sep 11 Javascript
在vue中使用axios实现post方式获取二进制流下载文件(实例代码)
Dec 16 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数组转换js数组操作及json_encode的用法详解
2013/10/26 PHP
Laravel学习教程之View模块详解
2017/09/18 PHP
发现的以前不知道的函数
2006/09/19 Javascript
大家未必知道的Js技巧收藏
2008/04/07 Javascript
JS 树形递归实例代码
2010/05/18 Javascript
用nodejs访问ActiveX对象,以操作Access数据库为例。
2011/12/15 NodeJs
jQuery对Select的操作大集合(收藏)
2013/12/28 Javascript
浅谈JavaScript function函数种类
2014/12/29 Javascript
coffeescript使用的方式汇总
2015/08/05 Javascript
AngularJS中如何使用$http对MongoLab数据表进行增删改查
2016/01/23 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
2016/04/13 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
JS实现unicode和UTF-8之间的互相转换互转
2017/07/05 Javascript
在页面中引入js的两种方法(推荐)
2017/08/29 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
2018/01/08 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
超轻量级的js时间库miment使用解析
2019/08/02 Javascript
vue.js实现h5机器人聊天(测试版)
2020/07/16 Javascript
vuex管理状态仓库使用详解
2020/07/29 Javascript
python文件的md5加密方法
2016/04/06 Python
Python SqlAlchemy动态添加数据表字段实例解析
2018/02/07 Python
python 获取键盘输入,同时有超时的功能示例
2018/11/13 Python
python二维键值数组生成转json的例子
2019/12/06 Python
python识别验证码图片实例详解
2020/02/17 Python
Python print不能立即打印的解决方式
2020/02/19 Python
Python日志处理模块logging用法解析
2020/05/19 Python
Python参数传递机制传值和传引用原理详解
2020/05/22 Python
html5使用canvas实现跟随光标跳动的火焰效果
2014/01/07 HTML / CSS
中层干部岗位职责
2013/12/18 职场文书
村官工作鉴定评语
2014/01/27 职场文书
搞笑车尾标语
2014/06/23 职场文书
大学生实习证明范文(5篇)
2014/09/18 职场文书
部队反四风对照检查材料
2014/09/26 职场文书
昆虫记读书笔记
2015/06/26 职场文书
2016年秋季开学典礼新闻稿
2015/11/25 职场文书