JavaScript 深拷贝与浅拷贝的区别

       JavaScript有两种数据类型,基础数据类型和引用数据类型。基础数据类型都是按值访问的,我们可以直接操作保存变量中的实际值,而引用类型如Array,我们不能直接操作对象的堆内存空间,引用类型的值都是按引用访问的,即保存在变量对象中的一个地址。

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

浅拷贝(shallow copy):只复制指向某个对象的指针,而不复制这个对象本身,新旧对象共享一块内存。

深拷贝(deep copy):复制并创建一个一模一样的对象,不共享内存,修改新对象旧对象不会变。

var a = 25;
var b = a;
b = 10;
console.log(a);//25
console.log(b);//10

浅拷贝:

//浅拷贝
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 40;
console.log(obj1);// { a: 10, b: 40, c: 30 } 
console.log(obj2);// { a: 10, b: 40, c: 30 }

深拷贝:

//深拷贝
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 40;
console.log(obj1);// { a: 10, b: 20, c: 30 }
console.log(obj2);// { a: 10, b: 40, c: 30 }

二.浅拷贝的实现

var json1 = {"a":"name","arr1":[1,2,3]}
function copy(obj1) {
    var obj2 = {};
    for (var i in obj1) {
      obj2[i] = obj1[i];
    }
    return obj2;
}
var json2 = copy(json1);
json1.arr1.push(4);
alert(json1.arr1);  //1234
alert(json2.arr1)  //1234

三.深拷贝的实现

1.Object.assign()
      Object.assign()是一种可以对非嵌套对象进行深拷贝的方法,如果对象中出了嵌套情况,那么其对被嵌套对象的行为就成了普通的浅拷贝。
let foo = {
    a: 1,
    b: 2,
    c: {
        d: 1,
    }
}
let bar = {};
Object.assign(bar, foo);
foo.a++;
foo.a === 2 //true
bar.a === 1 //true
foo.c.d++;
foo.c.d === 2 //true
bar.c.d === 1 //false
bar.c.d === 2 //true

2.转成json

用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

ar obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);   // { body: { a: 10 } } 
console.log(obj2);   // { body: { a: 20 } }
console.log(obj1 === obj2);   // false
console.log(obj1.body === obj2.body);   // false

这种方法的缺陷是会破环原型链,并且无法拷贝属性值为function的属性。

3.递归

采用递归的方法去复制拷贝对象。

var json1={"name":"shauna","age":18,"arr1":[1,2,3,4,5],"string":'got7',"arr2":[1,2,3,4,5],"arr3":[{"name1":"shauna"},{"job":"web"}]};
var json2={};
function copy(obj1,obj2){
  var obj2=obj2||{};
  for(var name in obj1){
    if(typeof obj1[name] === "object"){ 
      obj2[name]= (obj1[name].constructor===Array)?[]:{}; 
      copy(obj1[name],obj2[name]); 
    }else{
      obj2[name]=obj1[name];  
    }
  }
  return obj2;
}
json2=copy(json1,json2)
json1.arr1.push(6);
alert(json1.arr1);  //123456
alert(json2.arr1);  //12345

原文地址:https://blog.csdn.net/Shauna_Wu/article/details/79508988

猜你喜欢

转载自blog.csdn.net/GXing007/article/details/82115206
今日推荐