js中的深拷贝和浅拷贝与值传递和引用传递有着些许的关联,都是根据堆栈中数据的储存来传递数据。
下面主要说一下我对深拷贝和浅拷贝的理解:
简单举个例子来说明;当我们声明一个a变量并且赋值,并且让b等于a,因为a,b都是基本数据类型所以数据都是存储在栈中,所以改变其中一个变量的数据他们之间不会相互干扰的,这种拷贝就是深拷贝。而浅拷贝就是改变其中一个变量或者对象等参数的值或者属性,另外一个变量或者对象等参数的值或者属性也会发生变化。
深拷贝
var a=8,b=a;
var b=9;
console.log(a,b); //8,9
堆栈储存过程如下:
或者换一种情况:
var tal = new Object();
function test(obj){
obj.name = 'lili';
obj.id = 2;
}
test(tal);
tal.name = 'kiki';
console.log(tal); //{name:'kiki',id:2}
当我们创建tal对象的时候:
obj对象在函数中赋值的时候:
当函数调用之后,tal=obj,就是把obj的在栈中的地址付给对象tal,但是他们指向堆中的数据都是一个堆的数据。
改变tal.name的时候:
这样改变对象tal属性的时候就是改变obj对象的属性,这时候就是浅拷贝,无法做到改变tal数据,obj的数据不变。
如果想要深拷贝可以用以下两种方法:
一、用JSON对象的parse和stringify
function test(obj){
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone
}
var tal = {name:'lili'};
Cal=test(tal);
Cal.name = 'kiki';
console.log(tal,Cal); //{name: "lili"} {name: "kiki"}
这样就可以实现深拷贝,改变Cal对象的属性而不会改变tal对象的属性。
二、用jquery中的extend
$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
var tal = {name:'lili'};
Cal=$.extend(true,{},tal);
tal.name='kiki';
console.log(tal,Cal); //{name: "kiki"}{name: "lili"}
这样也可以实现深拷贝,深拷贝的作用一般就是多个人开发一个项目需要使用接口返回的相同数据,但是又不能相互干扰,这时候需要把数据进行深拷贝,从而对拷贝后的数据进行操作,以免影响原始数据。