還經(jīng)常有一些公司要求,原生手寫實(shí)現(xiàn),這篇文章主要介紹了js中對象深拷貝方法總結(jié),需要的朋友可以參考下" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js中對象深拷貝方法總結(jié)

 更新時(shí)間:2022年10月15日 16:00:44   投稿:wdc  
js深拷貝這個(gè)問題,在實(shí)際的工作和面試當(dāng)中也是經(jīng)常使用到的。
還經(jīng)常有一些公司要求,原生手寫實(shí)現(xiàn),這篇文章主要介紹了js中對象深拷貝方法總結(jié),需要的朋友可以參考下

快速克?。ù嬖跀?shù)據(jù)丟失問題) – JSON.parse/stringify

如果不在對象中使用Date、functions、undefined、Infinity、RegExps、Maps、Sets、blob、FileLists、ImageDatas、或其他復(fù)雜類型,則深入克隆對象庫可以使用非常簡單的一行代碼。

簡單的來說有以下問題:

  • 會(huì)忽略 undefined
  • 會(huì)忽略 symbol
  • 不能序列化函數(shù)
  • 不能解決循環(huán)引用的對象
JSON.parse(JSON.stringify(object))
const a = {
  string: 'string',
  number: 123,
  bool: false,
  nul: null,
  date: new Date(),  // stringified
  undef: undefined,  // lost
  inf: Infinity,  // forced to 'null'
  re: /.*/,  // lost
}
console.log(a);
console.log(typeof a.date);  // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date);  // result of .toISOString()

使用第三方框架

由于克隆對象并不簡單(復(fù)雜類型、循環(huán)引用、函數(shù)等),大多數(shù)主要庫都提供了克隆對象的功能。不要重新發(fā)明輪子-如果你已經(jīng)在使用一個(gè)庫,檢查它是否有對象克隆功能。例如:

  • lodash  cloneDeep;可以通過lodash.cloneDeep模塊單獨(dú)導(dǎo)入,如果之前你沒使用過lodash,那么lodash是一個(gè)非常不錯(cuò)的選擇。
  • AngularJS  angular.copy
  • jQuery – jQuery.extend(true, { }, oldObject).clone() 只能克隆DOM

ES6

為了完整起見,請注意ES6提供了兩種淺拷貝機(jī)制:Object.assign()和拓展運(yùn)算符語法。它將所有可枚舉的自身屬性的值從一個(gè)對象復(fù)制到另一個(gè)對象。例如:

var A1 = {a: "2"};
var A2 = Object.assign({}, A1);
var A3 = {...A1};  // 拓展運(yùn)算符

原生實(shí)現(xiàn)深拷貝

原生手寫深拷貝代碼,在面試當(dāng)中經(jīng)常遇到,雖然在實(shí)際項(xiàng)目開發(fā)中不是很常用,但大家還是需要熟練掌握手寫代碼的思想,因?yàn)檎娴拿嬖嚱?jīng)常考到呀~

function deepClone(obj) {
  function isObject(o) {
    return (typeof o === 'object' || typeof o === 'function') && o !== null
  }

  if (!isObject(obj)) {
    throw new Error('非對象')
  }

  let isArray = Array.isArray(obj)
  let newObj = isArray ? [...obj] : { ...obj }
  Reflect.ownKeys(newObj).forEach(key => {
    newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
  })

  return newObj
}

let obj = {
  a: [1, 2, 3],
  b: {
    c: 2,
    d: 3
  }
}
let newObj = deepClone(obj)
newObj.b.c = 1
console.log(obj.b.c) // 2

MessageChannel

MessageChannel 也是一個(gè)可以實(shí)現(xiàn)深拷貝的方式。

function structuralClone(obj) {
  return new Promise(resolve => {
    const { port1, port2 } = new MessageChannel()
    port2.onmessage = ev => resolve(ev.data)
    port1.postMessage(obj)
  })
}

var obj = {
  a: 1,
  b: {
    c: 2
  }
}

obj.b.d = obj.b

// 注意該方法是異步的
// 可以處理 undefined 和循環(huán)引用對象
const test = async () => {
  const clone = await structuralClone(obj)
  console.log(clone)
}
test()

更多關(guān)于js中對象深拷貝方法請查看下面的相關(guān)鏈接

相關(guān)文章

最新評論