深拷贝和浅拷贝是javascript中一个比较复杂的问题,也是面试官最喜欢问的问题之一,通过这个为可以看出是否入门,深拷贝和浅拷贝也是初学者经常犯错一个点。

简单来说深拷贝是拷贝储存在栈中的对象,而浅拷贝是从内存中拷贝,这就涉及到数据存放位置了,总所周知,数据大体可以分为两种数据类型,一种是基本数据类型,数据结构不是很复杂,单独可以存在内存中就可以,而另一种是复杂数据类型,也叫引用数据类型,例如数组和对象,是放在栈中存储的,而基本数据类型是放在内存中的,不涉及深拷贝和浅拷贝,也可以说基本数据类型都是深拷贝

而引用类型数据存储比较复杂,例如var a=[1,3,4]  这句话的存储就是首先在内存开辟一个空间,但是内存当中不可以存储这种复杂数据类型,所以要把这种结构放到栈当中,栈相当于一个密码箱,而钥匙存在内存当中,这就构成了一个存储关系,浅拷贝var b=a简单来说就是把这份钥匙复制了一份,但内存当中的数据并没有复制,所以如果改变a相应b也会改变

而深拷贝则需要在栈中在生成一个密码箱,生成一把新钥匙(钥匙2),这样深拷贝的两种数值不会相互影响,也可以说没有任何关系了

方法:

1:jq使用,$.extend({},obj)

2:Object.assign({},obj)

这两种比较基础,估计都会使用

3:clone(obj)

var clone = function (obj) { return JSON.parse(JSON.stringify(obj)); }
这种方法有种缺陷,这种方法会忽略值为function以及undefied的字段,而且对date类型的支持也不太友好。

4:clone(obj)

var clone = function (obj) {
if(obj === null) return null
if(typeof obj !== 'object') return obj;
if(obj.constructor===Date) return new Date(obj);
var newObj = new obj.constructor (); //保持继承链
for (var key in obj) {
if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性
var val = obj[key];
newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
}
}
return newObj;
};
这种方法也就使封装最好的深拷贝的方法,以下为解释:

1、用new obj.constructor ()构造函数新建一个空的对象,而不是使用{}或者[],这样可以保持原形链的继承;
2、用obj.hasOwnProperty(key)来判断属性是否来自原型链上,因为for..in..也会遍历其原型链上的可枚举属性。
3、上面的函数用到递归算法,在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题。但问题是这个函数的执行与函数名 factorial 紧紧耦合在了一起。为了消除这种紧密耦合的现象,需要使用 arguments.callee。
---------------------
作者:zuggs_
来源:CSDN
原文:https://blog.csdn.net/zuggs_/article/details/84784933
版权声明:本文为博主原创文章,转载请附上博文链接!

js对象的深拷贝及其的几种方法的更多相关文章

  1. js对象之间的"继承"的五种方法

    今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个"动物"对象的构造函数. function Animal(){ this.species = & ...

  2. JavaScript进阶(四)js字符串转换成数字的三种方法

    js字符串转换成数字的三种方法 在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b. ...

  3. Jsp页面跳转和js控制页面跳转的几种方法

    Jsp 页面跳转的几种方法 1. RequestDispatcher.forward() 在服务器端起作用,当使用forward()时,Servlet engine传递HTTP请求从当前的Servle ...

  4. js 动态加载事件的几种方法总结

    本篇文章主要是对js 动态加载事件的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助   有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添 ...

  5. js如何动态创建表格(两种方法)

    js如何动态创建表格(两种方法) 一.总结 一句话总结: 1.方法一:写好创建表格的html代码,将之赋值给div的innerHTML. 2.方法二.直接用创建好的table元素的方法insertRo ...

  6. js中常用追加元素的几种方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. javascript获取json对象的key名称的两种方法

    javascript获取json对象的key名称的两种方法 数据处理中,你可能接收到一个不确定内容格式的json对象,然后要把key的值提取出来.今天试过两种可以提取json key的方法,均可以正常 ...

  8. 原生JS—实现图片循环切换的两种方法

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...

  9. js 控制页面跳转的5种方法

    js 控制页面跳转的5种方法 编程式导航: 点击跳转路由,称编程式导航,用js编写代码跳转. History是bom中的 History.back是回退一页 Histiory.go(1)前进一页 Hi ...

随机推荐

  1. 如何在php7.2/php7.3中安装mcrypt扩展?

    mcrypt 是php里面重要的加密支持扩展库,linux环境下该库在默认情况下不开启.window环境下,PHP>=5.3,默认开启mcrypt扩展.mcrypt扩展是mcrypt加密库的接口 ...

  2. vue里使用element饿了么的el-menu+vue-router实现路由跳转的两种方法

    最近准备写一个echarts的可视化展示案例,首先用vue-cli3创建了一个项目(好像vue-cli4也出来,感觉变化不大,就没升级了) 然后,开始配置路由↓下面是我的router.js文件 imp ...

  3. 0级搭建类001-RedHat Enterprise Linux 8 安装(RHEL 8) 公开

    项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...

  4. 9Front fqa 目录

    9Front System 9Front 常见问答(fqa) 注意! 9front dash1 手册是由 9front 用户编写的. 这些用户有能做的,有不能写的:那些不能写的写了这本电子杂志.-- ...

  5. Codeforces Round #614 (Div. 2) D

    变色失败 只加8分 距离变色只差5分 B题没想到那么简单,结论秒猜,不敢交,傻傻验证5分钟. C题也想了码了好一会儿,我动态维护set做的. 1小时3题,整体难度好像没以前那么大了?(虽然也不强,但比 ...

  6. 简单理解Linux系统的挂载是什么鬼

    转载自http://c.biancheng.net/view/2859.html Linux系统中“一切皆文件”,所有文件都放置在以根目录为树根的树形目录结构中.在 Linux 看来,任何硬件设备也都 ...

  7. 【Python】表白程序

     程序链接:https://www.lanzous.com/i8xj5mh # 打包操作 # 安装pyinstaller # cmd输入 pip install pyinstaller # shift ...

  8. 【转载】深入理解Java虚拟机笔记---运行时栈帧结构

    栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区的虚拟机栈(Virtual Machine Stack)的栈元素.栈帧存储了方法的局部变量表,操作 ...

  9. Wannafly Camp 2020 Day 6F 图与三角形 - 图论

    把黑边视为无边,那么答案之和每个点的度数有关 #include <bits/stdc++.h> using namespace std; #define int long long int ...

  10. JS变量和数据类型及其转化

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...