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

JavaScript?深拷貝的循環(huán)引用問題詳解

 更新時(shí)間:2022年12月27日 15:27:17   作者:是廖一啊  
如果說道實(shí)現(xiàn)深拷貝最簡單的方法,我們第一個(gè)想到的就是?JSON.stringify()?方法,因?yàn)镴SON.stringify()后返回的是字符串,所以我們會再使用JSON.parse()轉(zhuǎn)換為對象,這篇文章主要介紹了JavaScript?深拷貝的循環(huán)引用問題,需要的朋友可以參考下

如果說道實(shí)現(xiàn)深拷貝最簡單的方法,我們第一個(gè)想到的就是 JSON.stringify() 方法,因?yàn)镴SON.stringify()后返回的是字符串,所以我們會再使用JSON.parse()轉(zhuǎn)換為對象,如下代碼:

let obj = { name: 'liaoyi',age: 22,sex: 1}
JSON.parse(JSON.stringify(obj))

但是這種克隆不夠完美,有一個(gè)致命的問題無法解決,就是她一旦遇到循環(huán)引用就會報(bào)錯(cuò):

let obj = { name: 'liaoyi',age: 22,sex: 1}
JSON.parse(JSON.stringify(obj))
obj.c = obj
console.log(JSON.stringify(obj))

js會報(bào)錯(cuò),無法把一個(gè)循環(huán)引用轉(zhuǎn)成 json 格式:

在這種情況下,我們通常想到的是寫一個(gè)正兒八經(jīng)的深度克隆方法:

使用傳統(tǒng)方式實(shí)現(xiàn)對象的深拷貝

function deepClone(obj) {
  const objectMap = new Map();
  const _deepClone = value => {
    const type = typeof value;
    if (type !== 'object' || type === null) {
      return value;
    }
    if (objectMap.has(value)) {
      return objectMap.get(value);
    }
    const result = Array.isArray(value) ? [] : {};

    objectMap.set(value, result);

    for (const [key, _v] of Object.entries(value)) {
      result[key] = _deepClone(value[key]);
      console.log(key, _v);
    }
    return result;
  };
  return _deepClone(obj);
}

使用 MessageChannel 實(shí)現(xiàn)循環(huán)引用對象的深拷貝

不夠新鮮,我們來看一個(gè)好玩的 Web API

參考鏈接: MessageChannel

MessageChannel允許我們在不同的瀏覽上下文,比如window.open()打開的窗口或者iframe等之間建立通信管道,并通過兩端的端口(port1和port2)發(fā)送消息。MessageChannel以DOM Event的形式發(fā)送消息,所以它屬于異步的宏任務(wù)。

// 通過這個(gè)構(gòu)造函數(shù),創(chuàng)建一個(gè)消息通道,它會返回一個(gè)對象,解構(gòu) port1, port2 來實(shí)現(xiàn)通信
const { port1, port2 } = new MessageChannel();
port1.postMessage('hello')
port2.onmessage = msg => {
  console.log(msg.data)  // hello
}

我們可以利用這個(gè)API,實(shí)現(xiàn)循環(huán)引用對象的深拷貝:

 function deepClone(obj) {
  return new Promise(resolve => {
    const { port1, port2 } = new MessageChannel();
    port1.postMessage(obj);

    port2.onmessage = msg => {
      resolve(msg.data);
      // console.log(obj, msg.data === obj); // false
    };
  })
}

 const obj = { a: 1, b: '2' }
 obj.c = obj; 
 deepClone(obj).then(res =>{
  console.log('res',res);
 })

到此這篇關(guān)于JavaScript 深拷貝的循環(huán)引用問題 _的文章就介紹到這了,更多相關(guān)JavaScript 深拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論