分享幾個用於深複製的方法

本篇摘要:主要分享了 JS 中常用的幾種深複製方法,有來自於vuex``jQuery``JSON``lodash``immutable中的經典方法,如果有需要,你可以進一步去研究它們的源碼。


1、使用 vuex源碼中的deepCopy()方法

/**
   * Deep copy the given object considering circular structure.
   * This function caches all nested objects and its copies.
   * If it detects circular structure, use cached copy to avoid infinite loop.
   *
   * @param {*} obj
   * @param {Array<Object>} cache
   * @return {*}
   */
  function deepCopy (obj, cache) {
    if ( cache === void 0 ) cache = [];

    // just return if obj is immutable value
    if (obj === null || typeof obj !== 'object') {
      return obj
    }

    // if obj is hit, it is in circular structure
    var hit = find(cache, function (c) { return c.original === obj; });
    if (hit) {
      return hit.copy
    }

    var copy = Array.isArray(obj) ? [] : {};
    // put the copy into cache at first
    // because we want to refer it in recursive deepCopy
    cache.push({
      original: obj,
      copy: copy
    });

    Object.keys(obj).forEach(function (key) {
      copy[key] = deepCopy(obj[key], cache);
    });

    return copy
  }

2、JSON.parseJSON.stringify

var obj = { a: 1, b: 2 }
var copy = JSON.parse(JSON.stringify(obj))

3、jQuery 中 extend()

const copy = jQuery.extend([deep], target, object1, [objectN])

4、使用 lodash 工具庫

import _ from 'lodash'
const b=_.cloneDeep(a)

5、使用 immutable 工具庫

import { Map } from 'immutable'

const imA = Map({
    username:'馬雲',
    money:150000000000,
    info:{ married:true, witticism:'我沒見過錢,我對錢不感興趣' }
})
const imB = Map({
    username:'laoxie',
    gender:'男',
    info:{ married:false, age:18 }
})
const newImData = imA.merge(imB);
console.log(newImData.toJS());
//輸出 :
// {
//     username:'laoxie',
//     gender:'男',
//     money:150000000000,
//     info:{ married:false, age:18 }
// }

const newImData = imA.mergeDeep(imB);
//輸出 :
// {
//     username:'laoxie',
//     gender:'男',
//     money:150000000000,
//     info:{ married:false, age:18, witticism:'我沒見過錢,我對錢不感興趣' }
// }

6、自己封裝深複製方法

function deepClone(target) {
  if (typeof (target) !== 'object') {
    return target;
  }
  var result;
  if (Object.prototype.toString.call(target) == '[object Array]') {
    // 數組
    result = []
  } else {
    // 對象
    result = {};
  }
  for (var prop in target) {
    if (target.hasOwnProperty(prop)) {
      result[prop] = deepClone(target[prop])
    }
  }
  return result;
}


本篇結束,感謝點贊!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章