深拷贝和浅拷贝是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. IO流学习之字节流(一)

    IO流(Input/Output) 简介: 流是一种抽象概念,它代表了数据的无结构化传递.按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列.从流中取得数据的操作称为提取操作,而向流中添加数 ...

  2. P1339 热浪【最短路】

    #include <bits/stdc++.h> #define dbg(x) cout << #x << "=" << x < ...

  3. 【Vue2.x笔记3】从源码看watch对象

    初始化 function initWatch (vm: Component, watch: Object) { for (const key in watch) { const handler = w ...

  4. Vue tinymce富文本编辑器

    tinymce 官方为 vue 项目提供了一个组件 tinymce-vue 一.安装tinymce-vue npm install @tinymce/tinymce-vue -S 二.下载tinymc ...

  5. 服务起不来,查看ps axj 看服务是否为守护进程(TPGID 为-1)

    在linux命令行中输入: ps axj 查看服务进程的 TPGID 字段的值是否为-1 ,为-1表示为守护进程 不为-1表示不是守护进程,服务启动不起来,或者启动起来后又被杀死了

  6. mysql 视图、触发器、事务、存储过程、函数

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  7. 141.内置上下文处理器debug、request、auth、messages、media、static、csrf

    上下文处理器 上下文处理器可以返回一些数据,在全局模板中都可以使用,比如登录后的用户数据,在很多页面中都需要使用,那么我们就可以方在上下文处理器中,就没有必要在每个视图中返回这个对象了. 在setti ...

  8. C++野指针的存在方式和误区

    1. char* x;这样的一定是野指针,指针声明时要直接初始化!或者置null也行! 2. int main() { char *x=new char; delete x; cout<< ...

  9. vue踩坑:vue+ element ui 表单验证有值但验证失败。

    一.如图:有值但是验证失败 二. <el-form :model="form" :rules="rules"> <el-form-item l ...

  10. “公文流转系统 v1.0”

    1.项目需求: 河北金力集团是我省机械加工的龙头企业,主要从事矿山机械制造及各种机械零部件加工.企业有3个厂区,主厂区位于省高新技术开发区,3个分厂分别在保定.邢台和唐山.为增加企业的核心竞争力和加强 ...