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中的delete操作符详细介绍
Jun 06 Javascript
使用jquery.validate自定义方法实现"手机号码或者固话至少填写一个"的逻辑验证
Sep 01 Javascript
浅谈JS闭包中的循环绑定处理程序
Nov 09 Javascript
利用JS生成博文目录及CSS定制博客
Feb 10 Javascript
移动端js图片查看器
Nov 17 Javascript
Vue.js中兄弟组件之间互相传值实例
Jun 01 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
Aug 03 Javascript
详解Vue2.0配置mint-ui踩过的那些坑
Apr 23 Javascript
Vue.js标签页组件使用方法详解
Oct 19 Javascript
微信小程序实现滚动加载更多的代码
Dec 06 Javascript
前端深入理解Typescript泛型概念
Mar 09 Javascript
webpack+vue.js构建前端工程化的详细教程
May 10 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
一个阿拉伯数字转中文数字的函数
2006/10/09 PHP
php下用cookie统计用户访问网页次数的代码
2010/05/09 PHP
JSON用法之将PHP数组转JS数组,JS如何接收PHP数组
2015/10/08 PHP
php封装的连接Mysql类及用法分析
2015/12/10 PHP
PHP在线书签系统分享
2016/01/04 PHP
PHP 数组基本操作方法详解
2016/06/17 PHP
表单提交验证类
2006/07/14 Javascript
html中使用javascript调用本地程序(exe、doc等)实现代码
2013/04/26 Javascript
jquery ajax jsonp跨域调用实例代码
2013/12/11 Javascript
全国省市二级联动下拉菜单 js版
2016/05/10 Javascript
vue自定义指令实现v-tap插件
2016/11/03 Javascript
使用clipboard.js实现复制功能的示例代码
2017/10/16 Javascript
jquery animate动画持续运动的实例
2017/11/29 jQuery
解决vue-cli创建项目的loader问题
2018/03/13 Javascript
解决vue的 v-for 循环中图片加载路径问题
2018/09/03 Javascript
vue-cli项目代理proxyTable配置exclude的方法
2018/09/20 Javascript
浅谈layui 数据表格前后台传值的问题
2019/09/12 Javascript
JavaScript实现简单计算器
2020/03/19 Javascript
详解Python的Django框架中manage命令的使用与扩展
2016/04/11 Python
Python实现网络端口转发和重定向的方法
2016/09/19 Python
tensorflow实现对图片的读取的示例代码
2018/02/12 Python
python使用socket创建tcp服务器和客户端
2018/04/12 Python
Python文件循环写入行时防止覆盖的解决方法
2018/11/09 Python
python networkx 包绘制复杂网络关系图的实现
2019/07/10 Python
opencv 获取rtsp流媒体视频的实现方法
2019/08/23 Python
Python Collatz序列实现过程解析
2019/10/12 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
Python气泡提示与标签的实现
2020/04/01 Python
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
澳大利亚儿童鞋在线:The Trybe
2019/07/16 全球购物
面试求职的个人自我评价
2013/11/16 职场文书
夏季奶茶店创业计划书
2014/01/16 职场文书
三八妇女节趣味活动方案
2014/08/23 职场文书
2015自愿离婚协议书范本
2015/01/28 职场文书
总经理岗位职责范本
2015/04/01 职场文书
2016年小学优秀班主任事迹材料
2016/02/29 职场文书