深拷贝和浅拷贝的区别

参考答案

一、深拷贝和浅拷贝的区别

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—

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧