js implements deep copy (full)

1. Using third-party libraries

Use method (see lodash Chinese official website for detailslodash )cloneDeep()

import lodash from 'lodash';

let obj = {
    
    
  a: {
    
    
    b: '阿潔'
  },
  c: '深拷贝'
}

const newObj = lodash.cloneDeep(obj)

2. Simple deep copy

In addition to the basic data type ( null、string、boolean、undefined、number、symbol), if there are no time type and regular expression objects in the reference data type, simple JSON serialization can be used for conversion.

let cloneObj = JSON.parse(JSON.stringify(obj))

Note: This deep copy is not recommended if the object content item is undefined, null, Date, RegExp, function... may cause problems

3. Recursive version

1. Considering the existence of a deep copy of Date and regular expressions (considering the most complete and relatively complicated deep copy)

export function cloneDeep(data) {
    
    
  //string,number,bool,null,undefined,symbol
  //object,array,date
  if (data && typeof data === "object") {
    
    
    //针对函数的拷贝
    if (typeof data === "function") {
    
    
      let tempFunc = data.bind(null);
      tempFunc.prototype = cloneDeep(data.prototype);
      return tempFunc;
    }
    // 根据不同的数据类型的深拷贝
    switch (Object.prototype.toString.call(data)) {
    
    
      case "[object String]":
        return data.toString();
      case "[object Number]":
        return Number(data.toString());
      case "[object Boolean]":
        return new Boolean(data.toString());
      case "[object Date]":
        return new Date(data.getTime());
      case "[object Array]":
        var arr = [];
        for (let i = 0; i < data.length; i++) {
    
    
          arr[i] = cloneDeep(data[i]);
        }
        return arr;

      //js自带对象或用户自定义类实例
      case "[object Object]":
        var obj = {
    
    };
        for (let key in data) {
    
    
          //会遍历原型链上的属性方法,可以用hasOwnProperty来控制 (obj.hasOwnProperty(prop)
          obj[key] = cloneDeep(data[key]);
        }
        return obj;
    }
  } else {
    
    
    //string,number,bool,null,undefined,symbol
    return data;
  }
}

2. Does not consider the deep copy of Date and regular expressions (the simplified version above is also a commonly used one)

function cloneDeep (target) {
    
    
  // 判断是否是对象
  if (typeof target === 'object') {
    
    
    // 兼容数组与对象
    let obj = Array.isArray(target) ? [] : {
    
    }
    for (let key in target) {
    
    
      obj[key] = cloneDeep(target[key])
    }
    return obj
  } else {
    
    
    return target
  }
}

Guess you like

Origin blog.csdn.net/qq_44094296/article/details/127093033