探讨深拷贝与浅拷贝之前,要先回顾一下值传递与援用传递:

值传递:var a = 10;var b = a;b++;//console.log(a,b)//a:10 b:11援用传递:var arr = [10,20,30,40];var arr1 = arr;arr1[0] = 40;//console.log(arr,arr1);//[40,20,30,40] [40,20,30,40]

一、浅拷贝(援用传递)

(1)概念

浅拷贝:当一个对象拷贝另一个对象的数据的时候,只有一个对象的数据产生扭转另一个对象的数据也会产生扭转因为浅拷贝拷贝的是援用的地址,(所以必须在对象是多层能力拷贝,单层拷贝的是数值,多层阐明外面套着对象,所以拷贝的是地址。)

(2)实现形式

办法一(ES6的办法):Object.assign()  作用:将第二个参数及当前的参数合并到第一个对象里。参数1:target参数2:对象......参数3:对象....//这个办法只会拷贝一层!不会拷贝第二层!例:  var obj = {a:{name:"kaiqin",age:19}}; var obj1 = Object.assign({},obj); obj1.a.name="wang" console.log(obj1)//{a: {name: "wang", age: 19}} console.log(obj)//{a: {name: "wang", age: 19}}办法二:应用  for  in 循环,遍历每一个属性,将他们赋值给新的对象。 要求对象必须是多层的状态下能力实现浅拷贝var obj = { a: {name:"kaiqin",age:19 } } ;function copy(obj){ var newObj = {}; for(var key in obj){ newObj[key] = obj[key]; }return newObj;}var obj1 = copy(obj);obj1.a.name="wang"console.log(obj1)//a: {name: "wang", age: 19}console.log(obj)//a: {name: "wang", age: 19}办法三:$.extend() 除了能够给jquery对象扩大办法外还能够实现深浅拷贝 1、布尔值 如果填true的状况下是深考贝 什么也不写就是浅拷贝 2、指标对象、数组 3......前面所有的对象 都是须要合并的对象var obj = {a:{name:"kaiqin",age:19}};var obj1 = {b:{name:"wang",age:19}};var obj2 = $.extend({},obj,obj1)obj2.a.name="zhang";console.log(obj2)//{a: {name: "zhang", age: 19},b: {name: "wang", age: 19}}console.log(obj)//{a: {name: "zhang", age: 19}}

二、深拷贝

(1)概念

当一个对象拷贝另一个对象的数据的时候,其中一个对象的数据发生变化不会影响另一个对象的数据因为深考贝拷贝的是对象的数据而不是地址

(2)实现办法

办法一:对象是单层的状况下Object.assign()//这个只拷贝一层,再来一层就废了 如上var obj = {a:1,b:2,c:3}var obj1 = Object.assign({},obj);obj1.a = 30;console.log(obj1,obj)//obj1==>{a:1,b:2,c:3}//obj==>{a:30,b:2,c:3}办法二:差不多比拟完满$.extend() 除了能够给jquery对象扩大办法外还能够实现深浅拷贝 1、布尔值 如果填true的状况下是深考贝 什么也不写就是浅拷贝 2、指标对象 3......前面所有的对象 都是须要合并的对象var obj = {a:{name:"kaiqin",age:19}};var obj1 = {b:{name:"wang",age:19}};var obj2 = $.extend(true,{},obj,obj1);obj2.a.name="zhang";console.log(obj2)//{a: {name: "zhang", age: 19},b: {name: "wang", age: 19}}console.log(obj)//{{a:{name:"kaiqin",age:19}}}办法三:JSON.parse、JSON.stringfiy      不能拷贝函数,但用在拷贝数据库数据时,不影响。因为数据库没有函数。所以举荐应用其原理是:先将对象转换为字符串、再转换成对象,此时地址肯定产生了变动,所以能够实现浅拷贝。var obj1 = {b:{name:"wang",age:19}};var obj2 = JSON.parse(JSON.stringify(obj1));   //此时地址产生了扭转。obj2.b.name = "kaiqin";console.log(obj1,obj2)

slice和concat对对象数组的拷贝,整个拷贝还是浅拷贝,拷贝之后数组各个值的指针还是指向雷同的存储地址。
因而,slice和concat这两个办法,仅实用于对不蕴含援用对象的一维数组的深拷贝
应用slice和concat对数组的深拷贝和浅拷贝:链接