js object深拷貝

javascript的傳參都是引用傳遞。下面的代碼

function mutate(obj) {
  obj.a = true;
}

const obj = {a: false};
mutate(obj)
console.log(obj.a); 

答案:1: prints true 2: prints false

正確答案是1.因?yàn)檫@里正是通過(guò)引用來(lái)傳參的。

那么下面這樣是否可以呢?答案已經(jīng)已經(jīng)可以看到了,這里的Object.assign是一種淺拷貝,對(duì)于obj里面還有嵌套的對(duì)象時(shí),一樣存在引用傳遞的問(wèn)題

const obj = /* ... */;
const copy = Object.assign({}, obj);
function mutateDeepObject(obj) {
  obj.a.thing = true;
}

const obj = {a: {thing: false}};
const copy = Object.assign({}, obj);
mutateDeepObject(copy)
console.log(obj.a.thing); // prints true

還有object.spread同樣是創(chuàng)建一個(gè)淺拷貝

當(dāng)然,有時(shí)你可能想要完全拷貝一個(gè)對(duì)象,作為參數(shù)去傳遞,從而不影響原有的對(duì)象。下面是介紹幾種深拷貝的例子

1,json.parse

const obj = /* ... */;
const copy = JSON.parse(JSON.stringify(obj));

怎么樣,可能你曾用過(guò),這里就是深拷貝的引用。

但是對(duì)Maps, Sets, RegExps, Dates, ArrayBuffers等不適用。

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

const obj = /* ... */;
const clone = await structuralClone(obj);

這里的消息對(duì)象 obj接收方就是一個(gè)深拷貝對(duì)象.這里是一種異步深拷貝。下面的state則是同步深拷貝的應(yīng)用

3.History API

function structuralClone(obj) {
  const oldState = history.state;
  history.replaceState(obj, document.title);
  const copy = history.state;
  history.replaceState(oldState, document.title);
  return copy;
}

const obj = /* ... */;
const clone = structuralClone(obj);

這里的 state每次都是一次深拷貝.(safari限制30ms內(nèi)最多調(diào)用100次)

4.Notification API

function structuralClone(obj) {
  return new Notification('', {data: obj, silent: true}).data;
}

const obj = /* ... */;
const clone = structuralClone(obj);

這種方式受瀏覽器權(quán)限限制,會(huì)比較慢。由于某些原因safari會(huì)返回 undefined

總結(jié):實(shí)際中使用時(shí),可以優(yōu)先使用
1,JSON.parse(JSON.stringify())性能最佳且各支持種瀏覽器
2.MessageChanne 支持各種瀏覽器

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容