一篇文章让你了解深拷贝,浅拷贝

109 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

1.赋值

赋值是将某一数值或对象赋给某个变量的过程

  • 基本数据类型:赋值,赋值之后两个变量互不影响
  • 引用数据类型:赋,两个变量具有相同的引用,指向同一个对象,相互之间有影响 通常在开发中并不希望改变变量 a 之后会影响到变量 b,这时就需要用到浅拷贝和深拷贝。

2.浅拷贝,深拷贝区别

深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。

  • 拷贝:只拷贝一层,更深层对象级别的只是拷贝引用。 (是同一个内存地址)
  • 深拷贝:拷贝多层,每一个级别的数据都会拷贝。 区别:深拷贝和浅拷贝最根本的区别在于。浅拷贝与原数据指向的是同一个内存地址,深拷贝 如何区分:对于复杂一点的对象B复制了A,修改A时看B是否发生变化:B变化了是浅拷贝,B没有变化是深拷贝

3.浅拷贝实现

简单来说可以理解为浅拷贝只解决了第一层的问题,拷贝第一层的基本类型值,以及第一层的引用类型地址。

实现方法:1. 利用for in遍历对象 2.利用Object.assgin();

3.Array.concat()或 a.slice() 只针对数组

let o = {
  id: 1,
  name: 'cao',
  msg: { age: 18 }
  }
let obj = {};
for (var k in o) {
 obj[k] = o[k]
}
 o.msg.age = 20;
 o.name = "cao1"
 或者:Object.assign(obj, o); 

详解:浅拷贝只拷贝了一层,因此name作为第一层的基数据,没有影响 msg作为引用数据,只拷贝了引用地址,因此有影响

let a = [1, 2, 3, 4],
b = a.slice();
a[0] = 2;
console.log(a, b);

4.深拷贝实现

深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。 当对象和它所引用的对象一起拷贝时即发生深拷贝。 深拷贝相比于浅拷贝速度较慢并且花销较大。 拷贝前后两个对象互不影响。

实现方法:1. 利用for in + 递归 2.利用Json.parse(Json.stringfy(object)); 方法1:JSON.parse(JSON.stringify(object)) 缺陷: 会忽略 undefined 会忽略 symbol 不能序列化函数 不能解决循环引用的对象

1.方法1

  let o = {
   name: 'cao',
   msg: { age: 18 }
   }
 let obj = {};
 obj = JSON.parse(JSON.stringify(o))
 o.msg.age = 20;
 o.name = "cao1";
 console.log(obj);
 console.log(o);

2.方法2 使用for in 循环+递归 ; instanceof判断循环出来的对象是否是数组,对象,如果是就递归。

let o = {
 id: 1,
 name: 'cao',
 msg: { age: 18, other: { color: "red" } },
 num: [1, 3, 4]
 }
let obj = {};


function deep(oldObj, newObj) {
 for (var k in oldObj) {
  var item = oldObj[k];
  if (item instanceof Array) {//判断是否为数组
   newObj[k] = [];
   newObj[k] = deep(item, newObj[k]);
   } else if (item instanceof Object) {//判断是否为对象
    newObj[k] = {};
    newObj[k] = deep(item, newObj[k])
    } else {//基本数据类型
       newObj[k] = item;
       }
  }
 return newObj
}
 deep(o, obj)
 o.msg.age = 20;
 o.name = "cao1";