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 相关文章推荐
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
Sep 20 Javascript
js 判断一个元素是否在页面中存在
Dec 27 Javascript
javascript数组去重方法终极总结
Jun 05 Javascript
JavaScript中判断页面关闭、页面刷新的实现代码
Aug 27 Javascript
使用coffeescript编写node.js项目的方法汇总
Aug 05 Javascript
jQuery mobile类库使用时加载导航历史的方法简介
Dec 04 Javascript
Bootstrap登陆注册页面开发教程
Jul 12 Javascript
jQuery右下角悬浮广告实例
Oct 17 Javascript
关于Vue.js一些问题和思考学习笔记(1)
Dec 02 Javascript
Bootstrap table右键功能实现方法
Feb 20 Javascript
微信小程序位置授权处理方法
Jun 13 Javascript
详解Vite的新体验
Feb 22 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
php上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
深入PHP数据缓存的使用说明
2013/05/10 PHP
PHP实现根据浏览器跳转不同语言页面代码
2013/08/02 PHP
php取整函数ceil,floo,round的用法及介绍
2013/08/31 PHP
laravel 4安装及入门图文教程
2014/10/29 PHP
thinkPHP多域名情况下使用memcache方式共享session数据的实现方法
2016/07/21 PHP
PHP页面输出时js设置input框的选中值
2016/09/30 PHP
PHP5.6读写excel表格文件操作示例
2019/02/26 PHP
根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码
2007/02/22 Javascript
js function定义函数使用心得
2010/04/15 Javascript
Jquery 获取指定标签的对象及属性的设置与移除
2014/05/29 Javascript
jQuery实现按钮的点击 全选/反选 单选框/复选框 文本框 表单验证
2015/06/25 Javascript
window.onload使用指南
2015/09/13 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
2016/10/26 Javascript
JS实现JSON.stringify的实例代码讲解
2017/02/07 Javascript
jQuery插件开发发送短信倒计时功能代码
2017/05/09 jQuery
JavaScript实现旋转轮播图
2020/08/18 Javascript
详解cordova打包成webapp的方法
2017/10/18 Javascript
[45:38]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第一局
2016/03/02 DOTA
python下读取公私钥做加解密实例详解
2017/03/29 Python
Python迭代器与生成器用法实例分析
2018/07/09 Python
对python中的乘法dot和对应分量相乘multiply详解
2018/11/14 Python
Python从数据库读取大量数据批量写入文件的方法
2018/12/10 Python
详解解决Python memory error的问题(四种解决方案)
2019/08/08 Python
python用Tkinter做自己的中文代码编辑器
2020/09/07 Python
python之语音识别speech模块
2020/09/09 Python
Python Socket多线程并发原理及实现
2020/12/11 Python
英国领先的在线鱼贩:The Fish Society
2020/08/12 全球购物
Ibatis如何使用动态表名
2015/07/12 面试题
捷科时代的软件测试笔试题
2015/11/09 面试题
四年级下册教学反思
2014/02/01 职场文书
银行类自荐信
2014/02/04 职场文书
创业计划实施的7大步骤
2014/02/05 职场文书
高中生家长寄语大全
2014/04/03 职场文书
初一学生评语大全
2014/04/24 职场文书
班主任远程培训研修日志
2015/11/13 职场文书