参考答案
一、深拷贝和浅拷贝的区别
1. 浅拷贝
- 只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
- 如果原地址发生改变,那么浅复制出来的对象也会相应的改变。
2. 深拷贝
- 增加了一个指针,并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
- 深拷贝开辟一个新的一样的内存地址用于存放复制的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
- 例如,假设B复制了A,当修改A时,看B是否会变化,如果B跟着改变,是浅拷贝,如果B没变,是深拷贝。
二、深拷贝和浅拷贝的实例
1.浅拷贝
//此递归方法不包含数组对象 var obj = { a:1, arr: [2,3] }; var shallowObj = shallowCopy(obj); function shallowCopy(src) { var newobj = {}; for (var prop in src) { if (src.hasOwnProperty(prop)) { newobj[prop] = src[prop]; } } return newobj; }
因为浅复制只会将对象的各个属性进行复制,并不会进行递归复制,而JavaScript存储对象是存地址的,所以浅复制会导致Obj.arr和shallowObj.arr指向同一块内存地址:
结果:
shallowObj.arr[1] = 5; console.log(obj.arr[1]); //5
2.深拷贝
var obj = { a:1, arr: [1,2], nation : '中国', birthplaces:['北京','上海','广州'] }; var obj2 = {name:'杨'}; obj2 = deepCopy(obj,obj2); console.log(obj2); //深复制,要想达到深复制就需要用递归 function deepCopy(o, c){ var c = c || {}; for(var i in o){ if(typeof o[i] === 'object'){ if(o[i].constructor === Array){ //这是数组 c[i] = []; }else{ //这是对象 c[i] = {}; } deepCopy(o[i], c[i]); }else{ c[i] = o[i]; } } return c; }
深复制不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象,也依次采用深复制的方法递归复制到新对象上,不会存在obj和shallowObj的arr属性指向同一个对象的问题。
obj1和obj2分别拥有不同的内存地址,两边的值改变互不影响。
三、深拷贝和浅拷贝的实现
1.浅拷贝
实例:
var a = [1, 2, 3, 4, 5]; var b = a; a[0] = 2 console.log(a); console.log(b);
结果:
//因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值) //b会随着a的变化而变化 //[2, 2, 3, 4, 5] //[2, 2, 3, 4, 5]
2.深拷贝
实例:
function deepClone(obj) { var newObj = obj instanceof Array ? []:{}; if(typeof obj !== 'object') { return obj; }else{ for(var i in obj) { newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]; } } return newObj; } var a = [1, 2, 4, 6, "a", "12", [1, 2]]; var b = deepClone(a); a[3] = 7; console.log(a); console.log(b);
结果:
//b对象并没有因为a对象的改变而改变,因为b深拷贝a [ 1, 2, 4, 7, 'a', '12', [ 1, 2 ] ] [ 1, 2, 4, 6, 'a', '12', [ 1, 2 ] ]
以上,是Java面试题【深拷贝和浅拷贝的区别】的参考答案。
输出,是最好的学习方法。
欢迎在评论区留下你的问题、笔记或知识点补充~
—end—