javascript进阶篇深拷贝实现的四种方式


Posted in Javascript onJuly 07, 2022

概念介绍

深拷贝:在堆内存中重新开辟一个存储空间,完全克隆一个一模一样的对象 浅拷贝:不在堆内存中重新开辟空间,只复制栈内存中的引用地址。本质上两个对象(数组)依然指向同一块存储空间

第一种:递归方式(推荐,项目中最安全最常用)

使用递归的方式进行对象(数组)的深拷贝

奉上已封装的深拷贝函数?

//函数拷贝
    const copyObj = (obj = {}) => {
    		//变量先置空
            let newobj = null;  
            //判断是否需要继续进行递归
            if (typeof (obj) == 'object' && obj !== null) {
                newobj = obj instanceof Array ? [] : {};
                //进行下一层递归克隆
                for (var i in obj) {
                    newobj[i] = copyObj(obj[i])
                }
                //如果不是对象直接赋值
            } else newobj = obj;
            return newobj;    
        }

上方函数的使用方式?

//模拟对象
let obj = {
	numberParams:1,
	functionParams:() => {
		console.log('昨天基金全是绿的,只有我的眼睛是红的');
	},
	objParams:{
		a:1,
		b:2
	}
}
const newObj = copyObj(obj); //这样就完成了一个对象的递归拷贝
obj.numberParams = 100;  //更改第一个对象的指
console.log(newObj.numberParams); //输出依然是1 不会跟随obj去改变

第二种:JSON.stringify() ;(这个不推荐使用,有坑)

这个方法有坑,详细讲解请看我另一篇文章 “使用JSON.stringify进行深拷贝的坑” 以下是代码示例

let obj = {
	a:1,
	b:"基金亏太多,终有一天,你站上了天台,我卧上了轨道。来生我们有说有笑。"
}
//先转为json格式字符,再转回来
let newObj = JSON.parse(JSON.stringify(obj));
obj.a = 50;
console.log(newObj.a); //输出 1

普通的对象也可以进行深拷贝,但是!!! 当对象内容项为number,string.boolean的时候,是没有什么问题的。但是,如果对象内容项为undefined,null,Date,RegExp,function,error的时候。使用JSON.stringify()进行拷贝就会出问题了。 详细讲解请查看我的另一篇文章“使用JSON.stringify()进行深拷贝的坑”

第三种:使用第三方库lodash中的cloneDeep()方法

是否推荐使用,看情况吧。如果我们的项目中只需要一个深拷贝的功能,这种情况下为了一个功能引入整个第三方库就显得很不值得了。不如写一个递归函数对于项目来说性能更好。

lodash.cloneDeep()代码示例?

import lodash from 'lodash';
let obj = {
	a: {
	    c: 2,
	    d: [1, 3, 5],
	    e:'阿巴阿巴'
	  },
	  b: 4
}
const newObj = lodash.cloneDeep(obj);
obj.b = 20;
console.log(newObj.b); //输出 4; 不会改变

实际上,cloneDeep()方法底层使用的本来就是递归方法。只是在外层又封装了一层而已。

所以,如果不是原先项目中有使用 lodash 这个库的话,大可不必为了这一个功能而去引入它。

文章上方有提供进行深拷贝的函数,推荐使用。大家可自取。

第四种:JQuery的extend()方法进行深拷贝(推荐在JQ中使用)

这个方法仅适用于JQuery构建的项目。 JQuery自身携带的extend()方法可以进行深拷贝,不用自己写递归也不用引入第三方库还没什么坑。

在JQuery项目中的使用方式?

let obj = {
	a: {
	    c: 2,
	    d: [1, 3, 5],
	    e:'阿巴阿巴'
	  },
	  b: 4
}
let newObj= $.extend(true, {}, obj1);  //拷贝完成
obj.b = 20;
console.log(newObj.b); //输出 4

总结

进行深拷贝的方法

  • 递归函数 (推荐使用,项目中使用的更多,更小,更安全)
  • JSON.stringify() 和JSON.parse() ; (不推荐使用,如果遇到Function,Date等类型的变量容易出现一些意料之外的问题)
  • 第三方库lodash的cloneDeep()方法 (就情况而定,如果项目中原先就有lodash这个第三方库,可以使用,否则还是推荐使用递归函数。不然成本太高。)
  • JQuery的extend()函数 (推荐在JQuery项目中使用,其他项目依然推荐是用递归函数)

以上就是javascript进阶篇深拷贝实现的四种方式的详细内容,更多关于javascript深拷贝的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
js DOM 元素ID就是全局变量
Sep 20 Javascript
js读写cookie实现一个底部广告浮层效果的两种方法
Dec 29 Javascript
Javascript中call与apply的学习笔记
Sep 22 Javascript
js下拉选择框与输入框联动实现添加选中值到输入框的方法
Aug 17 Javascript
AngularJS基础 ng-keydown 指令简单示例
Aug 02 Javascript
Vue实例简单方法介绍
Jan 20 Javascript
微信小程序开发中的疑问解答汇总
Jul 03 Javascript
JavaScript调试之console.log调试的一个小技巧分享
Aug 07 Javascript
微信小程序使用toast消息对话框提示用户忘记输入用户名或密码功能【附源码下载】
Dec 09 Javascript
Vuex实现购物车小功能
Aug 17 Javascript
js实现滚动条自动滚动
Dec 13 Javascript
如何用JS实现简单的数据监听
May 06 Javascript
js面向对象编程OOP及函数式编程FP区别
Jul 07 #Javascript
类和原型的设计模式之复制与委托差异
JS高级程序设计之class继承重点详解
Jul 07 #Javascript
JS class语法糖的深入剖析
Jul 07 #Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 #Javascript
js作用域及作用域链工作引擎
Promise静态四兄弟实现示例详解
Jul 07 #Javascript
You might like
15种PHP Encoder的比较
2007/03/06 PHP
PHP 开源框架22个简单简介
2009/08/24 PHP
浅谈php的优缺点
2015/07/14 PHP
thinkphp表单上传文件并将文件路径保存到数据库中
2016/07/28 PHP
JS解密入门 最终变量劫持
2008/06/25 Javascript
javascript 面向对象编程 聊聊对象的事
2009/09/17 Javascript
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
javascript时间自动刷新实现原理与步骤
2013/01/06 Javascript
jQuery setTimeout()函数使用方法
2013/04/07 Javascript
javascript特殊用法示例介绍
2013/11/29 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
探讨Vue.js的组件和模板
2017/10/27 Javascript
JavaScript类型相关的常用操作总结
2019/02/14 Javascript
原生JS实现图片懒加载之页面性能优化
2019/04/26 Javascript
jQuery事件委托代码实践详解
2019/06/21 jQuery
python使用点操作符访问字典(dict)数据的方法
2015/03/16 Python
Python判断Abundant Number的方法
2015/06/15 Python
Python函数中的函数(闭包)用法实例
2016/03/15 Python
python 打印出所有的对象/模块的属性(实例代码)
2016/09/11 Python
Python编程之列表操作实例详解【创建、使用、更新、删除】
2017/07/22 Python
Python实现matplotlib显示中文的方法详解
2018/02/06 Python
使用python搭建服务器并实现Android端与之通信的方法
2019/06/28 Python
利用anaconda作为python的依赖库管理方法
2019/08/13 Python
Python numpy数组转置与轴变换
2019/11/15 Python
python GUI库图形界面开发之PyQt5访问系统剪切板QClipboard类详细使用方法与实例
2020/02/27 Python
Python logging日志库空间不足问题解决
2020/09/14 Python
python邮件中附加文字、html、图片、附件实现方法
2021/01/04 Python
CSS3的 fit-content实现水平居中
2017/09/07 HTML / CSS
HTML里显示pdf、word、xls、ppt的方法示例
2020/04/14 HTML / CSS
陈欧的广告词
2014/03/18 职场文书
小学生个人先进事迹材料
2014/05/08 职场文书
法语专业求职信
2014/07/20 职场文书
2014县政府领导班子三严三实对照检查材料思想汇报
2014/09/26 职场文书
井冈山红色之旅心得体会
2014/10/07 职场文书
MySQL创建高性能索引的全步骤
2021/05/02 MySQL