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 相关文章推荐
Javascript事件热键兼容ie|firefox
Dec 30 Javascript
JavaScript获取和设置CheckBox状态的简单方法
Jul 05 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
Aug 08 Javascript
jQuery实现表格隔行及滑动,点击时变色的方法【测试可用】
Aug 20 Javascript
JS常用知识点整理
Jan 21 Javascript
Vue生命周期示例详解
Apr 12 Javascript
JavaScript 五大常见函数
Mar 23 Javascript
node 命令方式启动修改端口的方法
May 12 Javascript
解决mpvue + vuex 开发微信小程序vuex辅助函数mapState、mapGetters不可用问题
Aug 03 Javascript
cdn模式下vue的基本用法详解
Oct 07 Javascript
element-ui中Table表格省市区合并单元格的方法实现
Aug 07 Javascript
jquery将json转为数据字典的实例代码
Oct 11 jQuery
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
PHP备份数据库生成SQL文件并下载的函数代码
2012/02/05 PHP
php获取本地图片文件并生成xml文件输出具体思路
2013/04/27 PHP
PHP中array_map与array_column之间的关系分析
2014/08/19 PHP
php实现的返回数据格式化类实例
2014/09/22 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
layui数据表格自定义每页条数limit设置
2019/10/26 PHP
广告显示判断
2006/08/31 Javascript
将CKfinder整合进CKEditor3.0的新方法
2010/01/10 Javascript
jquery子元素过滤选择器使用示例
2013/06/24 Javascript
js 用CreateElement动态创建标签示例
2013/11/20 Javascript
jQuery 复合选择器应用的几个例子
2014/09/11 Javascript
JavaScript中的getMilliseconds()方法使用详解
2015/06/10 Javascript
基于jQuery的左滑出现删除按钮的示例
2017/08/29 jQuery
javascript中的replace函数(带注释demo)
2018/01/07 Javascript
Webpack path与publicPath的区别详解
2018/05/03 Javascript
React中嵌套组件与被嵌套组件的通信过程
2018/07/11 Javascript
小程序多图列表实现性能优化的方法步骤
2019/05/28 Javascript
手把手教你 CKEDITOR 4 实现Dialog 内嵌 IFrame操作详解
2019/06/18 Javascript
EasyUI 数据表格datagrid列自适应内容宽度的实现
2019/07/18 Javascript
vue使用微信JS-SDK实现分享功能
2019/08/23 Javascript
vue遍历对象中的数组取值示例
2019/11/07 Javascript
jQuery实现手风琴效果(蒙版)
2020/01/11 jQuery
用Python编写分析Python程序性能的工具的教程
2015/04/01 Python
Python读写ini文件的方法
2015/05/28 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
python使用pyqt写带界面工具的示例代码
2017/10/23 Python
python读写Excel表格的实例代码(简单实用)
2019/12/19 Python
Python如何脚本过滤文件中的注释
2020/05/27 Python
迪卡侬英国官网:Decathlon英国
2017/04/08 全球购物
本科生详细的自我评价
2013/09/19 职场文书
银行实习鉴定
2013/12/13 职场文书
《影子》教学反思
2014/02/21 职场文书
铣工实训报告
2014/11/05 职场文书
2015年组织部工作总结
2015/04/03 职场文书
2015年商场工作总结
2015/04/27 职场文书
适合后台管理系统开发的12个前端框架(小结)
2021/06/29 Javascript