原生Javascript深拷贝

深拷贝函数

实现代码可以直接复制,解析在下方

    /*** @parma {Object|Array} obj* @return {Object|Array} * 返回一个新的引用类型实现深拷贝**/function deepCopy(obj) {if (typeof obj !== 'object') return objvar target = Array.isArray(obj) ? [] : {}for (var key in obj) {target[key] = obj[key]if (typeof obj[key] == 'object') {target[key] = deepCopy(obj[key])}}return target}

浅拷贝和深拷贝

浅拷贝

  • 简单数据类型的赋值是在栈内开辟内存,直接存值

  • 复杂数据类型(引用类型)的赋值是在栈内留下地址,在堆内储存数据

  • 只在栈内实现

    • 复杂类型直接把一个变量赋给另一个变量时,只会把变量存的地址赋给另一个变量

    • 则浅拷贝是指复杂数据类型在赋值时,只把地址赋值给变量,两个变量都指向同一个堆里的数据,变量a的值改变,变量b的值也发生改变。这样具体实际应用意义不大,变量a,b都是同一个对象,那么用一个变量不就好了

深拷贝

  • 把对象(数组或复杂类型)a内的属性和值 一一遍历赋给变量b,如果对象a,其中某一属性的值是复杂类型则继续遍历此属性中的对象并赋值
var obj = {uname : '小明',age : 18,father : {uname : '爸爸',age : 48,wife:{uname:'妈妈',...}}
}var newObj = {}
newObj.uname = '小明'
newObj.age = 18
newObj.father = {}
newObj.father.uname = '爸爸'
newObj.father.age = 48
newObj.father.wife = {}
newObj.father.wife.uanem = '妈妈'
...

暴力拷贝

function deepCloen(obj) {// 当前循环的对象var cur = {}// obj为被循环的对象for (var key in obj) {if (typeof obj[key] === 'object') {cur[key] = deepCloen(obj[key])} else {cur[key] = obj[key]}}//  开始向上返回结果return cur
}

思路:创建空对象,判断当前循环是不是复杂类型,是的话则调用方法本身再次循环判断,如果是简单类型直接赋值,如果for in 循环结束遍历,说明本次所有结果都是简单类型,开始向上返回结果

方法缺点:如果是数组的话,也会被改为对象,简单但是不好用

实现深拷贝

 /*** @parma {Object|Array} obj* @return {Object|Array} * 返回一个新的引用类型实现深拷贝**/
function deepCopy(obj) {// 简单类型直接返回if (typeof obj !== 'object') return obj// 判断是数组还是对象var flag = Array.isArray(obj)// 当前循环的引用类型var cur = flag ? [] : {}for (var key in obj) {// if结构优化,先赋值,如果这次是对象,重新赋值cur[key] = obj[key]if (typeof obj[key] == 'object') {cur[key] = deepCopy(obj[key])}}// 循环到最后时开始向上返回值,把每次的结果return cur
}

思路:在暴力拷贝的基础上多了判断,flag作为判断标致,控制创建对象还是数组,并且for in循环也能拷贝数组

测试

var obj = {uname: '孙悟空',team: {master: '唐僧',shenxian: undefined,bros: [{ uname: '八戒', hobbit: 'eat' }, '沙僧', '小白龙']}
}function deepCopy(obj) {var flag = Array.isArray(obj)var target = flag ? [] : {}for (var key in obj) {target[key] = obj[key]if (typeof obj[key] == 'object') {target[key] = deepCopy(obj[key])}}return target
}// 测试
var myObj = deepCloen(swk)
console.log(myObj)
obj.team.bros[1] = '悟净'
obj.team.bros[0].hobbit = 'sleep'
console.log(obj);
  • 如果改变原对象obj的值,新对象myObj不会改变,说明深度拷贝实现

借助工具轻松实现

1.JSON newObj=JSON.parse(JSON.stringify(obj))// 不能识别undefined
2.jQuery  $.extend(true,newObj,obj)// 不能识别undefined
3.lodash  newObj=_.cloneDeep(obj)

深拷贝原生Javascript相关推荐

  1. 分享10个原生JavaScript技巧

    首先在这里要非常感谢无私分享作品的网友们,这些代码片段主要由网友们平时分享的作品代码里面和经常去逛网站然后查看源文件收集到的.把平时网站上常用的一些实用功能代码片段通通收集起来,方便网友们学习使用,利 ...

  2. animate用法 js原生_用 原生Javascript 创建带动画的固顶导航菜单

    当我们在网页中加入一个导航菜单的时候,需要考虑很多因素.如何确定它的位置?如何定义样式?还需要保证它具有良好的响应性.又或者你想为它添加一些炫酷的动画.这时你可能会对 jQuery 感兴趣,因为它会帮 ...

  3. mysql插入ㄖ_原生JavaScript代码100个实例

    1.原生JavaScript实现字符串长度截取 function cutstr(str, len) { var temp; var icount = 0; var patrn = /[^\x00-\x ...

  4. java文件异步上传_[Java教程]原生javascript实现文件异步上传

    [Java教程]原生javascript实现文件异步上传 0 2017-10-25 19:00:06 效果图: 代码:(demo33.jsp) demo33.jsp名称文件确定 本文网址:http:/ ...

  5. [译] 原生 JavaScript 值得学习吗?答案是肯定的

    原文地址:Is Vanilla JavaScript worth learning? Absolutely. 原文作者:David Kopal 译文出自:掘金翻译计划 本文永久链接:github.co ...

  6. React jsx转换成原生JavaScript的一个例子

    jsx代码: var React = require('react'); var ReactDOM = require('react-dom'); var MyButtonController = r ...

  7. 原生希望原生JavaScript开篇

    本篇文章个人在深圳游玩的时候突然想到的...最近就有想写几篇关于原生希望的文章,所以回家到之后就奋笔疾书的写出来发布了 一直对前端技巧很有兴致,就心生了写一个专栏的动机,然后就申请了原生JavaScr ...

  8. 一些常用且实用的原生 JavaScript函数[转]

    日常开始中常用到的一些原生JavaScript函数,比较实用, 今天特地整理一下,分享给大家,希望对大家有用,会常更新,同时也欢迎大家补充. css及html方面的技巧总结,点此前往: 前端开发中一些 ...

  9. 原生JavaScript轮播图效果实现

    原生JavaScript实现轮播图切换效果的实现过程 本文所用代码仅供个人学习.此部分代码系按原腾讯电脑管家首页的轮播图效果,采用原生JS技术予以实现(原网页采用jQurey等技术). 1. 文件准备 ...

最新文章

  1. 波士顿动力机器狗新技能!跳绳园艺做家务,还有书法神技
  2. 海信电视root工具_海信璀璨系列家电:一次购买便能享受全方位智能家居生活...
  3. AJAX中日历控件的应用
  4. Excel图表横坐标设置怎么做?(亲测)
  5. c语言for要分号错误,c语言for语句
  6. 华为云classroom应用_华为任正非:将来所有应用都会长在云土地上,但现在还不是...
  7. 何时使用JavaFX代替HTML
  8. 产品经理必备的两种心态
  9. python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__
  10. $bzoj1046-HAOI2007$ 上升子序列 $dp$ 贪心
  11. No package ‘glib-2.0‘ found/No package ‘gobject-2.0‘ found
  12. paip..net DATAGRIDVIEW表格里边加PROCESSBAR进度条控件总结
  13. 太阳能充电板给锂电池充电电路设计
  14. java 僵尸进程_僵尸进程ZOMBIE
  15. 建筑施工企业工程项目成本管理软件
  16. Ctrl、Alt、Shift常用的电脑快捷键大全(收藏级)
  17. 迷惘一代、沉默一代、X世代、Z世代……美国的几代人
  18. android 最好的gtd软件,这9款高质量APP让你工作效率提高50%!
  19. JixiPix Romantic Photo for Mac(照片浪漫效果软件)
  20. 【视野】解密腾讯完整前端技术体系

热门文章

  1. w7服务器搭建网站教程,w7系统下的云服务器搭建教程
  2. 从五新到百新,阿里终于要卷起裤腿干“新农业”了
  3. cqyz oj | 化装晚会 | 二分搜索 | 贪心
  4. 一张图学会Django
  5. 如果用户的计算机的配置较差,买电脑怎么看配置?电脑购买须知【详解】
  6. vue3 使用render函数渲染插槽,以Naive UI为例
  7. C语言入门 -- 打印工资总额、税金及净工资(2020/12/11)
  8. Markdown如何使用详细教程
  9. 物联网管理平台是怎样收费的?
  10. anaconda3、pycharm2019.3.3、python3.7搭建中文车牌识别系统环境