首页 > 其他 > 详细

深浅拷贝

时间:2020-12-16 22:55:35      阅读:43      评论:0      收藏:0      [点我收藏+]

1. 浅拷贝

js的数据类型,分为基本类型和引用类型

js基本类型:Number、String、Boolean, 其传值方式是按照按值传递的方式

var num1 = 1;
var num2 = num1;
num2 = 2;
此时的num1的值不受影响,仍为1;

但是引用类型就不同了,它是按引用传值

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 100, c: 30 } <-- b 被改到了
console.log(obj2);
// { a: 10, b: 100, c: 30 }

上面赋值,是引用赋值,是将 obj1 的地址复制给 obj2, obj1 和 obj2 指向的是同一个内存区域。因此对任何一个修改,其实修改的都是同一个对象,这就是所谓的浅拷贝。

2. 深拷贝

深拷贝会另外创造一个一模一样的对象,新旧对象不共享内存,因此修改其中的一个对象不会改到另一个对象。

深拷贝的几种方式

1. 手动复制

obj1 = {a:1,b:2}
obj2 = {a: obj1.a,b: obj.b}

2. 对象只有一层的话。可以用object.assign({},obj1)

Es6的object.assign()是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身

所以只能实现一层基本类型属性的拷贝 当obj1中属性是引用类型时,就会发现,修改其中一个属性值,另一个值也发生变化。 如下所示:

  let obj1 = {a: 1, b: { c: 2}}
  let obj2 = Object.assign({},obj1)
    // 或者 obj2 = {...obj1}
  obj2.b.c = 4
  console.log(obj1) //{ a: 1, b: { c: 4 } }

3. 转成json再转换回来

用JSON.stringify转为字符串 再用JSON.parse把字符串再转为新的对象

obj2 = JSON.parse(JSON.stringify(obj1))

坏处: 摒弃了对象的constructor,不管原来的constructor是什么,拷贝后都是object. 只能处理可以被json直接表示的数据结构,number,string,array,扁平对象;

boolean RegExp对象,无法通过此方式深拷贝

4. 递归拷贝

递归深拷贝的实现:

  var deepCopy = function(obj) {
  if (typeof obj !== ‘object‘) return
  var newObj = obj instanceof Array ? [] : {}
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = typeof obj[key] === ‘object‘ ? deepCopy(obj[key]) : obj[key]
    }
  }
  return newObj
}

缺点: 相互引用会出现死循环,深拷贝的做法是遇到对象就进行递归 复制,那么结果只能无限循环下去

5. object.create()方法

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

也就是说,现有对象是新的对象的构造函数的prototype.其实现过程如下:

function create(obj) {
  function F() {}
  F.prototype = obj
  return new F()
}

6. 直接使用一些库函数方法, 如lodash

var _ = require(‘lodash‘)
_.cloneDeep()



深浅拷贝

原文:https://www.cnblogs.com/SF9924/p/14145502.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!