值类型和引用类型,深层复制和浅层复制(深拷贝浅拷贝)最详细了
2018-02-28 17:23
113 查看
要知道深层复制浅层复制的区别,首先要了解值类型和引用类型。
变量分值类型和引用类型,深层复制和浅层复制都是针对引用类型变量的操作。
值类型: 比如数值,字符串,布尔,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---深拷贝,上代码:
呼~~完事,写的不能再详细了赶脚~,还画图简直累死宝宝惹,o(╥﹏╥)o~
变量分值类型和引用类型,深层复制和浅层复制都是针对引用类型变量的操作。
值类型: 比如数值,字符串,布尔,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~
相关文章推荐
- .net中String是引用类型还是值类型 以及 C#深层拷贝浅层拷贝
- Js从头学起(详细分析基本数据类型和引用类型的参数传递)
- js--引用类型Array--3.数组简单复制和深度复制
- C#引用类型详细剖析
- js中复制基本类型与复制引用类型值的区别
- Web19.引用类型对象拷贝
- 引用类型复制去除引用
- C++中,虚函数,引用指针,拷贝复制等知识点总结
- JS实现clone函数对五种数据类型的复制(深拷贝、浅拷贝)
- Swift 值类型,引用类型,深拷贝,浅拷贝,Copy,MutableCopy
- JS 函数与作用域 引用类型对象拷贝
- 引用类型的对象复制(浅复制和深复制)
- Javascript小知识点(七):数据类型赋值,浅拷贝,深拷贝(数组值传递还是引用传递)
- 值类型与引用类型及其对象复制
- python知识点(三):复制(引用、拷贝、浅拷贝和深拷贝)
- javascript复制变量值时,基本类型值和引用类型值异同
- Leetcode 39: python可变类型复制(浅拷贝和深拷贝)
- 值类型和引用类型的区别(详细分析)
- Js从头学起(基本数据类型和引用类型的参数传递详细分析)
- WeakHashMap和Java引用类型详细解析