深拷贝和浅拷贝两者的区别:

假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

用堆(heap)和栈(stack)来说:

浅拷贝是:B拷贝A时,AB指向同一个堆中的值;
深拷贝是:B拷贝A时,B会在堆中开辟出一个新的内存,与A并存。

深拷贝是在堆内存中开辟一个新的内存出来存储数据,是将对象和值复制过来,两个对象间互不影响。
浅拷贝是复制对象有引用地址,两个对象指向同一个地址,一个对象更改时,另一个对象也会更改。

浅拷贝,值的引用

  1. var a = [1, 2, 3, 4, 5];
  2. var b = a;
  3. a[0] = 2
  4. console.log(a);
  5. console.log(b);
  6. //因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值)
  7. //b会随着a的变化而变化
  8. //[2, 2, 3, 4, 5]
  9. //[2, 2, 3, 4, 5]

image.png

深拷贝,两都互不影响:

  1. function clone(source) {
  2. var target = {};
  3. for(var i in source) {
  4. if (source.hasOwnProperty(i)) {
  5. //Object的hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。
  6. //hasOwnProperty()这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链,来自:https://blog.csdn.net/i_dont_know_a/article/details/84324051
  7. //简单来说hasOwnProperty()就是判断自身属性是否存在原型(返回false)中还是实例(返回true)中
  8. target[i] = source[i];
  9. }
  10. }
  11. return target;
  12. }
  13. var obj = {a:1,b:2}
  14. var obj2 = clone(obj)
  15. obj2.a = 2
  16. // obj2 {a: 2, b: 2}
  17. // obj {a: 1, b: 2}

image.png

以上的两个实例只是对单层数据格式的实现

递归的方式实现深拷贝:

  1. function clone(source) {
  2. var target = {};
  3. for(var i in source) {
  4. if (source.hasOwnProperty(i)) {
  5. if (typeof source[i] === 'object') {
  6. target[i] = clone(source[i]); // 注意这里
  7. } else {
  8. target[i] = source[i];
  9. }
  10. }
  11. }
  12. return target;
  13. }
  14. var obj = {a:1,b:2,c:3}
  15. var obj2 = clone(obj)
  1. function deepClone(obj){
  2. let objClone = Array.isArray(obj)?[]:{};
  3. // Array.isArray() 方法用于判断一个对象是否为数组。
  4. if(obj && typeof obj==="object"){
  5. for(key in obj){
  6. if(obj.hasOwnProperty(key)){
  7. //判断obj子元素是否为对象,如果是,递归复制
  8. if(obj[key]&&typeof obj[key] ==="object"){
  9. objClone[key] = deepClone(obj[key]);
  10. }else{
  11. //如果不是,简单复制
  12. objClone[key] = obj[key];
  13. }
  14. }
  15. }
  16. }
  17. return objClone;
  18. }
  19. let a=[1,2,3,4],
  20. b=deepClone(a);
  21. a[0]=2;
  22. console.log(a,b);

JSON对象的stringify和parse实现深拷贝(缺点:无法复制函数类型):

  1. function deepClone(obj){
  2. let _obj = JSON.stringify(obj),
  3. objClone = JSON.parse(_obj);
  4. return objClone
  5. }
  6. let a=[0,1,[2,3],4],
  7. b=deepClone(a);
  8. a[0]=1;
  9. a[2][0]=1;
  10. console.log(a,b);
  11. a 输出 [1,1,[1,3],4]
  12. b 输出 [0,1,[2,3],4]

JQuery的extend方法

$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target 为Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

  1. let a=[0,1,[2,3],4],
  2. b=$.extend(true,[],a);
  3. a[0]=1;
  4. a[2][0]=1;
  5. console.log(a,b);
  6. a 输出 [1,1,[1,3],4]
  7. b 输出 [0,1,[2,3],4]

参考自:https://blog.csdn.net/HiSen_CSDN/article/details/103188104