要知道深层复制浅层复制的区别,首先要了解值类型和引用类型。
变量分值类型和引用类型,深层复制和浅层复制都是针对引用类型变量的操作。
值类型: 比如数值,字符串,布尔,undifined
引用类型 : 比如数组,对象,函数
来张图(手抖,有点丑):
var num = 77;
var id = 1234;
var cat = {name : '喵喵',age : 3 };
结合上面图,内存分两块区域,栈和堆。
值类型的数据保存在栈中;
引用类型的存储需要栈和堆共同完成,在栈中存放地址,该地址指向对应的堆内存中的数据。
看看区别
值类型:
var name = '周小七';
var other= name ;
name = '周小八'
console.log(other) ; //'周小七'
console.log(name == other) ;//false
引用类型:
var seven1 = {};
var seven2 = seven1;
seven1.name = '周小七';
console.log(seven2.name); //'周小七'
console.log(seven1 == seven2);//true
为什么? 因为他们都是指向同一个对象的,再来个丑图,哈哈:
基础讲完,开始看拷贝:
对象的实例是存储在堆内存中然后通过一个引用值去操作对象,由此拷贝的时候就存在两种情况了:拷贝引用和拷贝实例,这也是浅拷贝和深拷贝的区别。
浅拷贝
以上面的为例,var seven2 = seven1,这就是浅层复制,拷贝之后,seven1===seven2,这是浅拷贝的一种情况,直接拷贝源对象的引用,另外一种情况有点复杂,拷贝源对象的实例,但如果其属性值为复杂的数据类型,只拷贝其内层元素的引用,啥意思?上代码:
var a = [{m:1}, {n:2},3]; var b = a.slice(); console.log(b);//[{m:1}, {n:2},3] console.log(a === b);// false a[0].m = 4; console.log(b[0].m)//4,说明拷贝的是元素的引用 a[2] = 5; console.log(b[2])//3,说明拷贝的实例,(拷贝的a上面的3)
我拷贝你的时候,你里面属性值是值类型的,我直接拷走,你值类型再变化,我不受影响;你里面的属性值如果是复杂一些的引用类型,太重了,我拷不走,那我就只拷贝指向它的地址,当你这边值变化时,我那边也跟着变。一句话概括就是,看人下菜碟。哈哈哈,势利眼。。。。
深拷贝
深拷贝是克隆了一个一模一样的对象,目标是使 seven1 != seven2,深拷贝会开辟新的内存区域,地址指向不同的地方。深拷贝后的对象与原来的对象是完全隔离,互不影响
深拷贝怎么实现?
1. 来个最简单粗暴的(我个人常用),哈哈:
seven2 = JSON.parse(JSON.stringify(seven1));
大部分的时候可以用,局限:函数不能复制;原型链搞没了...
2. jQuery.extend() : 用于将一个or多个对象内容合并到目标对象:
$.extend( [deep ], target, object1 [, objectN ] )
deep默认false---浅拷贝(第二种浅拷贝,拷贝实例,内层属性值引用类型时,只拷贝内层元素的引用)
deep设置true---深拷贝,上代码:
var a = [{m:1}, {n:2},3]; var b =[]; $.extend(true,b,a); console.log(a === b);// false a[0].m = 4; console.log(b[0].m)//1 a[2] = 5; console.log(b[2])//3
这样无论a再怎么变化,都不会影响到b了。
呼~~完事,写的不能再详细了赶脚~,还画图简直累死宝宝惹,o(╥﹏╥)o~