实现浅拷贝和深拷贝

1. 浅拷贝和深拷贝的区别

简单点说,浅拷贝拷贝完后,修改拷贝的内容可能会对源内容产生影响。而深拷贝就是拷贝前后的内容相互不影响。

      那为什么拷贝前后的内容会相互影响呢?那就得知道原始数据类型和引用类型的区别了。

在内存中的存储方式不同,原始数据类型在内存中是堆存储,引用类型是栈存储 栈(stack)为自动分配的内存空间,它由系统自动释放;而堆(heap)则是动态分配的内存,大小不定也不会自动释放。在内存中存储方式的不同导致了原始数据类型不可变 原始数据类型和引用数据类型做赋值操作一个是传值一个是传址

  • 原始数据类型:自然不用说了,它的值就是一个数字,一个字符或一个布尔值。
  • 引用类型:是一个对象类型,值是什么呢?它的值是指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。

而在js中,有三大引用类型即Object、Array、Function。

因此在拷贝他们的时候,应该使用深拷贝来避免于源内容产生影响。

2.实现浅拷贝

2.1 object.assign()

 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];
var result= Object.assign(arr);
arr[2][a]='222';
console.log(arr);
//output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result);
//output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];

2.2 拓展运算符…

var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];

var result= [...arr];
arr[2][a]='222'; console.log(arr);
//output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result);
//output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];

以上两种方法很简单,一句话就搞定啦。

3.实现深拷贝

3.1 JSON

var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];
var result = JSON.parse(JSON.stringify(arr));
arr[2][a]='222';
console.log(arr);
//output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
console.log(result);
//output: [1, [7,[9]], {a:'111'}, null, null, null, null]

所以可以看出,使用JSON不能实现对function、undefined、NaN的拷贝

如果拷贝的数据不存在function、undefined、NaN这些数据类型的话,使用JSON是个很简便的方法呢。

3.2 递归遍历

想要对所有类型都能够实现深拷贝的话,那就只能自己封装个函数来实现啦。

var arr = [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN];

function deepCopy(arr) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if(obj[key]===null){newObj[key]=null;continue;}
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
} var result = deepCopy(arr));
arr[2][a]='222';
console.log(arr);
//output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
console.log(result);
//output: [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]

js实现浅拷贝和深拷贝的更多相关文章

  1. js对象浅拷贝和深拷贝详解

    js对象浅拷贝和深拷贝详解 作者:i10630226 字体:[增加 减小] 类型:转载 时间:2016-09-05我要评论 这篇文章主要为大家详细介绍了JavaScript对象的浅拷贝和深拷贝代码,具 ...

  2. Javascript/js 的浅拷贝与深拷贝(复制)学习随笔

    js变量的数据类型值分基本类型值和引用类型值. 在ES6(ECMAScript6)以前,基本数据类型包括String.Number.Boolean.Undefined.Null. 基本类型值的复制(拷 ...

  3. [转] js对象浅拷贝和深拷贝详解

    本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = ...

  4. js中浅拷贝和深拷贝以及深拷贝的实现

    前言:2019年的第一篇分享... 一.什么是基本类型值和引用类型值?ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型.基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构 ...

  5. js的浅拷贝和深拷贝和应用场景

    为什么会用到浅拷贝和深拷贝 首先来看一下如下代码 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e ...

  6. 小tips:JS之浅拷贝与深拷贝

    浅拷贝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷贝: functio ...

  7. js相关--浅拷贝和深拷贝

    1.js的数据类型 基本概述:js的数据类型分为两种,分别为基本数据类型和引用数据类型,它们俩的区别在于基本数据类型采用值传递,引用数据类型采用指针形式传递. 如下所示:引用类型通过简单的=进行复制, ...

  8. JS的浅拷贝与深拷贝

    浅拷贝 //这样的拷贝有一个问题.那就是,如果父对象的属性等于数组或另一个对象,//那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能. function exten ...

  9. js之浅拷贝与深拷贝

    浅拷贝:只会复制对象的第一层数据 深拷贝:不仅仅会复制第一层的数据,如果里面还有对象,会继续进行复制,直到复制到全是基本数据类型为止 简单来说,浅拷贝是都指向同一块内存区块,而深拷贝则是另外开辟了一块 ...

随机推荐

  1. mybatis工作流程

    1)通过Reader对象读取src目录下的mybatis.xml配置文件(该文本的位置和名字可任意) 2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory ...

  2. [Python]使用pytest进行单元测试

    安装pytest pipenv install pytest 验证安装的版本: pytest --version This , imported /site-packages/pytest.py 接下 ...

  3. PCD(点云数据)文件格式

    博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=54 为什么用一种新的文件格式? PCD文件格式并非白费力气地做重复工作,现有 ...

  4. 一百零二:CMS系统之sweetalert提示框和使用

    实现效果 css body.stop-scrolling { height: 100%; overflow: hidden; } .sweet-overlay { background-color: ...

  5. SpringBoot之解决一对一、多对一、多对多等关联实体在JSON序列化/输出时产生的无限递归死循环问题(infinite recursion)

    前言 这问题着实让人苦不堪言,有必要把它记下了. @JsonBackReference [亲测有效] 1.使用注解@JsonBackReference标记在有关联关系的实体属性上 2.仅导入此注解类有 ...

  6. java 与 c# 3des 加解密

    java 与 c# 3des 加解密   主要差异如下: 1.  对于待加密解密的数据,各自的填充模式不一样 C#的模式有:ANSIX923.ISO10126.None.PKCS7.Zero,而Jav ...

  7. python基础知识(字典)

    创建字典 变量名 = {key:value,.....} zip()    转换为zip对象 空字典 变量名 = {} 变量名 = dict(key = value,....) 创建只有键的字典 fr ...

  8. LeetCode.1217-交换芯片(Play with Chips)

    这是小川的第次更新,第篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第270题(顺位题号是1217).There are some chips, and the i-th ch ...

  9. NDK学习笔记-JNI开发流程

    JNI(Java Native Interface)Java本地化接口,Java调用C/C++,C/C++调用Java的一套API接口 实现步骤 在Java源文件中编写native方法 public ...

  10. ERNIE学习笔记

    https://ai.baidu.com/forum/topic/show/954092 学习ERNIE的输入部分 输入 一共有五个部分组成,每个部分之间用分号;隔开: · token_ids:输入句 ...