从新梳理下js中的深拷贝和浅拷贝

参考链接:
http://www.cnblogs.com/st-les…
https://blog.csdn.net/hj7jay/…

浅拷贝:

1.最简朴的浅拷贝就赋值。
因为js中的对象都是庞杂数据范例,这类数据在内存中存储的时刻,存放在堆中。当简朴赋值的时刻,实际上是将该对象的指针指向同一个堆地点。

简朴的数据范例存放在栈中,当对简朴的数据范例举行赋值的时刻,实在就是直接在栈中新拓荒一个处所特地来存储一样的值。

所谓的浅拷贝就是,背面的对象和前面的对象在第一层数据结构中指向同一个堆地点。然则假如前面的数据不止有一层,如:

let obj = { a: {a: "hello", b: 21} };

此时,运用Object.assign()和…Object体式格局完成的都是浅拷贝。
此时,第一层数据虽然指向了另一个新的堆地点,然则它内部的子对象的指针却照样同一个地点。这类状况也属于浅拷贝,只不过是比那种直接赋值(直接复制堆地点)的体式格局要深入一些。

2.数组和对象的浅拷贝

数组的浅拷贝,有三种体式格局:

(1) arr1 = arr2;
(2) arr2 = arr1.slice(0);
(3) arr2 = arr1.concat();

对象的浅拷贝,也有3种体式格局:

(1) obj2 = obj1;
(2) obj2 = Object.assign(obj1 ,{} )
(3) obj2 = {...obj1}

深拷贝

对象的深拷贝实际上就是,将前一个对象复制一份给背面的谁人对象,不论前面的谁人对象中的数据结构嵌套有多深,当转变个中一个对象中的恣意深度的某个值后,另一个对象中的该值不会受任何影响。

1.当对象中的一切属性值都是简朴数据范例的时刻:

function easyCopy(p) {
  var c = {};
  for (var i in p) {
    c[i] = p[i];
    }
  c.uber = p;
  return c;
}

2.当要复制的对象中存在某个属性的value值是对象或许数组时:
假如像上面的简朴范例那样直接赋值,那么子对象对应的属性实际上指向的是和被拷贝对象中子对象一样的内存地点。因而,只需改了一个,另一个也会随着转变。

function deepCopy(p, c) {
    let c = c || {};
    for (let i in p) {
        if(! p.hasOwnProperty(i)){
            continue;
        }
        if (typeof p[i] === 'object') {
            c[i] = (p[i].constructor === Array) ? [] : {};
            deepCopy(p[i], c[i]);
        } else {
            c[i] = p[i];
        }
    }
    return c;
}

Parent = {name: 'foo', birthPlaces: ['北京','上海','香港']}
var Child = deepCopy(Parent); 

总结:
浅拷贝:你变我也变,嵌套对象变,就会随着变。
深拷贝:管你怎样变,互不影响。

    原文作者:qinqinlv
    原文地址: https://segmentfault.com/a/1190000018204798
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞