深拷贝学习笔记

  • A+
所属分类:Web前端
摘要

var i = 5;var j = i;j=1;console.log(i);//5console.log(j);//1我们正常赋值的逻辑是像上面一样,复制一份下来,然后对复制的那一份进行操作,这样的逻辑是对的,但是这样的拷贝默认是浅拷贝,当出现以下情况时,这种写法就会出问题


在开发过程中,我碰到了一个问题,让我找了好久问题在哪里,最后我发现是最开始赋值的时候没有深拷贝值,导致了原本值被覆盖污染,这里和大家分享下我的解决方法

var i = 5;

var j = i;

j=1;

console.log(i);//5

console.log(j);//1

我们正常赋值的逻辑是像上面一样,复制一份下来,然后对复制的那一份进行操作,这样的逻辑是对的,但是这样的拷贝默认是浅拷贝,当出现以下情况时,这种写法就会出问题

var i = {

        value:5

};

var j = i;

j.value=1;

console.log(i.value);//1

console.log(j.value);//1

是不是觉得很奇怪,我在网上找了一下为什么,是有关浅拷贝和深拷贝的知识:

(浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针,出现深浅拷贝的情况是当对象为Object或Array时才会出现。)

我分享下我的三种种解决方法:

第一种,使用JSON.parse(JSON.stringify())

let arr = [1, 3, {

    username: ' kobe'

}];

let arr4 = JSON.parse(JSON.stringify(arr));

arr4[2].username = 'duncan';

console.log(arr, arr4)

原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

第二种:Object.assign()

var obj = { a: {a: "kobe", b: 39} };

var initalObj = Object.assign({}, obj);

initalObj.a.a = "wade";

console.log(obj.a.a); //wade

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

第三种:手写递归方法

递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

 function getType(obj) {
  //tostring会返回对应不同的标签的构造函数
  var toString = Object.prototype.toString;
  var map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  if (obj instanceof Element) {
    return 'element';
  }
  return map[toString.call(obj)];
}

//深拷贝
 function deepClone(data) {
  var type = getType(data);
  var obj;
  if (type === 'array') {
    obj = [];
  } else if (type === 'object') {
    obj = {};
  } else {
  //不再具有下一层次
    return data;
  }
  if (type === 'array') {
    for (var i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]));
    }
  } else if (type === 'object') {
    for (var key in data) {
      obj[key] = deepClone(data[key]);
    }
  }
  return obj;
}

 

如果大家有其他方法,也欢迎在下面分享ヽ( ̄▽ ̄)ノ