current position:Home>Front end interview question - Summary of object copy method

Front end interview question - Summary of object copy method

2021-08-26 17:39:42 stan

1. Object copy method

1.1 JSON.parse and JSON.stringify Method

utilize JSON.stringify and JSON.parse Method is a deep copy , But you can't copy functions and undefined, Nor can you copy properties and methods on the object prototype chain .

var obj = {
  a: 1,
  b: 2,
  c: {
    d: 4,
    //  In the analysis of  JSON  When the string ,undefined  Don't parse 
    e: undefined,
    // null  stay  JSON  In the string is  null => "f": null
    f: null
  },
  f: function () { console.log('function'); }
};
var newObj = JSON.parse(JSON.stringify(obj));
console.log(newObj.c.d); // 4
console.log(newObj.e); // undefined
console.log(newObj.f); // undefined

1.2 for-in loop

utilize for-in The loop is a shallow copy , Copy only basic types of data , For data of reference type , Only pointers are copied .

var obj = {
  a: 1,
  b: {
    c: 3
  }
};
var newObj = {};
for (var key in obj) {
  newObj[key] = obj[key];
}
newObj.b.c = 4;
console.log(obj.b.c); // 4
console.log(newObj.b.c); // 4

1.3 Object.assign Method

utilize Object.assign Method is a shallow copy , Copy enumerable and self owned properties in the source object .

var obj = {
  a: 1,
  b: {
    c: 3
  }
};
var newObj = {};
Object.assign(newObj, obj);
newObj.b.c = 4;
console.log(obj.b.c); // 4
console.log(newObj.b.c); // 4

1.4 Deconstruct assignment

The deconstruction assignment method is used for shallow copy .

var obj = {
  a: 1,
  b: {
    c: 1
  }
}
var newObj = {...obj}
newObj.b.c = 2
console.log(obj.b.c) // 2
console.log(newObj.b.c) // 2

2. Deep copy method of handwritten object

2.1 ES5 Implement object deep copy

function deepClone (origin, target) {
  var _tar = target || {}
  
  for (var key in origin) {
    if (origin.hasOwnProperty(key)) {
      if (typeof origin[key] === 'object' && origin[key] !== null) {
        _tar[key] = Object.prototype.toString.call(origin[key]) === '[object Array]' ? [] : {};
        deepClone(origin[key], _tar[key]);
      } else _tar[key] = origin[key];
    }
  }

  return _tar
}

var obj = {
  a: 1,
  b: 2,
  c: {
    d: 4,
    e: 5
  },
  f: function () { console.log('function'); }
};
var newObj = {};
deepClone(obj, newObj);
console.log(newObj.c.d); // 4
console.log(newObj.f); // undefined

2.2 ES6 Implement object deep copy

function deepClone (origin) {
  if (origin == undefined || typeof origin !== 'object') return origin;
  
  if (origin instanceof Date) return new Date(origin);
  if (origin instanceof RegExp) return new RegExp(origin);
  
  const target = new origin.constructor();
  
  for (let key in origin) {
    if (origin.hasOwnProperty(key)) {
      target[key] = deepClone(origin[key]);
    }
  }
  
  return target;
}

Can realize object deep copy , But when circular reference occurs, it will lead to dead loop . So we need to use WeakMap Save objects that have been copied , Prevent a dead cycle .

function deepClone (origin, hashMap = new WeakMap()) {
  if (origin == undefined || typeof origin !== 'object') return origin;

  if (origin instanceof Date) return new Date(origin);
  if (origin instanceof RegExp) return new RegExp(origin);
  
  const hashVal = hashMap.get(origin);
  if (hashVal) return hashVal;
  
  const target = new origin.constructor();
  hashMap.set(origin, target);
  
  for (let key in origin) {
    if (origin.hasOwnProperty(key)) {
      target[key] = deepClone(origin[key]);
    }
  }
  
  return target;
}

copyright notice
author[stan],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210826173938414Z.html

Random recommended