位置: 编程技术 - 正文

JavaScript深度复制(deep clone)的实现方法(用js实现一个复杂对象深拷贝的算法)

编辑:rootadmin

推荐整理分享JavaScript深度复制(deep clone)的实现方法(用js实现一个复杂对象深拷贝的算法),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:js数组深度复制,js深复制,js深复制函数,js数组深度复制,js深复制,js深浅复制,js深浅复制,js深复制和浅复制,内容如对您有帮助,希望把文章链接给更多的朋友!

在代码复用模式里面有一种叫做“复制属性模式”(copying properties pattern)。谈到代码复用的时候,很有可能想到的是代码的继承性(inheritance),但重要的是要记住其最终目标——我们要复用代码。继承性只是实现代码复用的一种手段,而不是唯一的方法。复制属性也是一种复用模式,它跟继承性是有所不同的。这种模式中,对象将从另外一个在对象中获取成员,其方法是仅需将其复制即可。用过jQuery的都知道,它有一个$.extend()方法,它的用途除了扩展第三方插件之外,还可以用来复制属性的。下面我们来看一个extend()函数的实现代码(注意这里的并不是jQuery的源码,只是一个简单的示例):

上面的代码是一个简单的实现,它仅遍历父对象的成员并将其复制到子对象中去。下面我们用上面的extend()方法来测试一下:

我们发现,extend()方法已经可以正常工作了。但是有一个问题,上面给出的是一种所谓的浅复制(shallow clone)。在使用浅复制的时候,如果改变了子对象的属性,并且该属性恰好又是一个对象,那么这种操作也会修改父对象,单是很多情况这不是我们想要的结果。考虑下列情况:

通过上面的例子,我们会发现,修改了kid.counts属性以后(把元素4追加进去了),dad.counts也会受到影响。这是因为在使用浅复制的时候,由于对象是通过引用传递的,即kid.counts和dad.counts指向的是同一个数组(或者说在内存上他们指向同一个堆的地址)。

下面,让我们修改extend()函数以实现深度复制。我们需要做的事情就是检查父对象的每一个属性,如果该属性恰好是对象的话,那么就递归复制出该对象的属性。另外,还需要检测该对象是否为一个数组,这是因为数组的字面量创建方式和对象的字面量创建方式不一样,前者是[],后者是{}。检测数组可以使用Object.prototype.toString()方法进行检测,如果是数组的话,他会返回"[object Array]"。下面我们来看一下深度复制版本的extend()函数:

好了,深度复制的函数已经写好了,下面来测试一下看是否能够预期那样子工作,即是否可以实现深度复制:

通过上面例子,我们可以发现,即使修改了子对象的kid.counts和kid.reads,父对象的dad.counts和kid.reads并没有改变,因此我们的目的实现了。

JavaScript深度复制(deep clone)的实现方法(用js实现一个复杂对象深拷贝的算法)

下面来总结一下实现深复制的的基本思路:

1.检测当前属性是否为对象

2.因为数组是特殊的对象,所以,在属性为对象的前提下还需要检测它是否为数组。

3.如果是数组,则创建一个[]空数组,否则,创建一个{}空对象,并赋值给子对象的当前属性。然后,递归调用extendDeep函数。

上面例子使我们自己使用递归算法实现的一种深度复制方法。事实上,ES5新增的JSON对象提供的两个方法也可以实现深度复制,分别是JSON.stringify()和JSON.parse();前者用来将对象转成字符串,后者则把字符串转换成对象。下面我们使用该方法来实现一个深度复制的函数:

下面是测试例子:

测试发现,它也实现了深度复制。一般推荐使用后面这种方法,因为JSON.parse和JSON.stringify是内置函数,处理起来会比较快。另外,前面的那种方法使用了递归调用,我们都知道,递归是效率比较低的一种算法。

关于JavaScript深度复制(deep clone)的实现方法就给大家介绍这么多,希望对大家有所帮助!

javascript每日必学之循环 朋友们大家好,今天,我们继续接着前面的内容讲,前们我们已经讲了条件分支,今天我们就讲循环,顾名思义就是,重复执行相同的操作,正常循环

javascript下使用Promise封装FileReader Promise在处理异步的时候是个很好的选择,可以减少嵌套层次,让代码更好读,逻辑更清晰。ES6将其加入规范,jQuery3.0也修改实现向规范靠拢(3.0发布公

js下将金额数字每三位一逗号分隔 工作中很常用的东西:例1,使数字变成,,.,保留两位小数。htmlheadscripttype="text/javascript"functionoutputmoney(number){number=number.replace(/,/g,"");if(isNaN

标签: 用js实现一个复杂对象深拷贝的算法

本文链接地址:https://www.jiuchutong.com/biancheng/380390.html 转载请保留说明!

上一篇:百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换(百度坐标转换成WGS84坐标)

下一篇:javascript每日必学之循环(javascript例题)

  • 个税申报的收入是应发还是实发
  • 增值税发票平台怎么下载已认证发票
  • 购入车辆进项如何做账
  • 为员工集中购买医疗保险
  • 残保金退回属于什么业务
  • 处置固定资产需要税务局备案吗
  • 应付职工薪酬期末余额怎么算
  • 发票专用章换了需要登记吗
  • 所得税申报表里季初资产是指什么
  • 固定资产与累计折旧有对应关系吗
  • 增值税零申报触发附加税零申报
  • 买二手房为什么要交个人所得税
  • 怎么处理未抵扣增值税形成的留抵税额?
  • 保险收入如何做账务处理?
  • 取得转账支票后该如何处理
  • 工程施工企业人工成本最高多少
  • 建筑工程公司项目经理职责
  • 季报每个月需要反写吗
  • 股票授予代替工资缴税吗?
  • 工资分两次发的风险是什么?
  • 微税平台抄税的步骤是怎样的?
  • 增加注册资本需要多少股东通过
  • 税控盘证书密码一天可以输几次
  • 汽车配件税收分类
  • 预收款项什么时候确认收入
  • 其他应付款转增股本
  • 十分钟看懂财务报表
  • 长租押金多少合适
  • 现金清查制度的内容包括
  • 怎么计算研发费用占销售收入总额比例
  • 工程物资期末余额应在资产负债表中填列?
  • hdmi连接电视无法全屏
  • 汽车销售公司购买车辆会计科目
  • 总包和分包是什么关系
  • 纳税评估一般程序包括
  • 厄勒布鲁赛程500
  • 公司法人往公司账户转钱会计分录
  • “write javaBean error, fastjson version 1.2.83, class org.apache.shiro.web.servlet.ShiroHttpServletR
  • flutter项目怎么运行
  • 基于stm32的飞行器
  • 论文导语如何写
  • numpy的简单例子
  • 国税申报系统操作流程
  • 消防工程材料费用占比
  • 已经提完折旧的房产价值评估
  • 公司采购不含税产品合法吗
  • 员工出差预借差旅费入的借贷
  • 弥补以前年度亏损是季度申报的时候做吗
  • 关联企业能否做法人代表
  • 存货在报表里是如何体现的
  • 增值税税率调整为13%从什么时候开始实行
  • 火车票可以抵扣进项吗
  • 公司购车购置税可以抵扣吗
  • 简易计税是否要计增值税
  • 会计税法的差异
  • 出口不退税进项税是否可以抵扣
  • 社保扣款上月没扣费
  • 记账凭证的基本要素包括
  • 净利润增长率计算方式
  • 单位统一订员工餐
  • 收到对方红字发票信息表怎么处理
  • 原材料入库单应根据采购订单还是到货数量
  • 销售预算的重要性
  • 无票收入怎么报增值税申报表
  • mysql安装使用教程
  • 深入了解XP中“最后一次正确配置”功能
  • cmd命令怎么运行
  • mozilla是啥
  • win7使用技巧图解
  • python图片处理酷炫效果
  • css旋转木马
  • python获取本地路径
  • nodejs事件队列
  • javascript中匿名函数
  • 上海税务发票自动抵扣
  • 江西税务局
  • 税控盘如何分配发票
  • 垃圾填埋税率
  • 打税务局电话
  • 税务局直属机构
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设