实现深浅拷贝的方法有哪些?

参考:js浅拷贝及深拷贝的几种方法

1、浅拷贝

(1) Object.assign()

参考:Object.assign()用法讲解

var obj1 = {a: 1, b: 2};
var obj2 = Object.assign({}, obj1);
(2) 解构赋值
var obj1 = {a: 1, b: 2};
var obj2 = {...obj1};

浅拷贝实现原理:

function shallowCopy(obj) {
  var target = {};
  for (let i in obj) {
    if (obj.hasOwnproperty(i)) {
      target[i] = obj[i];
    }
  }
  return target;
}

2、深拷贝

(1) 利用JSON.parse 和JSON.stringfy
var obj1 = {
  name: 'li',
  hobit: ['摄影', '羽毛球']
}
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.hobit.push('游泳');
console.log(obj1); //{ name: 'li', hobit: [ '摄影', '羽毛球' ] }
console.log(obj2); //{ name: 'li', hobit: [ '摄影', '羽毛球', '游泳' ] }
(2) 利用递归来实现

使用JSON.parse 和JSON.stringfy也会有很多限制:参考:关于JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑

  1. 如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
  2. 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;
  3. 如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
  4. 如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
  5. JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
  6. 如果对象中存在循环引用的情况也无法正确实现深拷贝;

可通过递归来实现一个深拷贝:

function deepCopy(obj) {
  if (obj == null)  return obj;
  if (obj instanceof Date) return new Date();
  if (obj instanceof RegExp) return new RegExp(obj);
  if (typeof obj !== 'object') return obj;
  let cloneObj = new obj.constructor();
  for (let i in obj) {
    if (obj.hasOwnproperty(i)) {
      cloneObj[i] = deepCopy(obj[i]);
    }
  }
  return cloneObj;
}
(3) jQuery的extend
$.extend( [deep ], target, object1 [, objectN ] )
  • deep :表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
  • target: Object类型 目标对象,其他对象的成员属性将被附加到该对象上
  • object1… objectN : Object类型 第一个以及第N个被合并的对象。

你可能感兴趣的:(#)