📜  如何使用 JavaScript 以类似 JSON 的格式打印圆形结构?

📅  最后修改于: 2022-05-13 01:56:37.691000             🧑  作者: Mango

如何使用 JavaScript 以类似 JSON 的格式打印圆形结构?

循环结构是当您尝试引用直接或间接引用自身的对象时。

例子:

A -> B -> A   OR   A -> A

在开发应用程序时,循环结构非常常见。例如,假设您正在开发一个社交媒体应用程序,其中每个用户可能有一个或多个图像。每个图像都可能引用其所有者。像这样的东西:

{
    User1: {
        Image1:{
            URL: 'Image Url',
            Owner: User1 (object)
        },
        Image2:{
            URL: 'Image Url',
            Owner: User1 (object)
        }
    }
}

在这里,您可以通过将用户 ID 传递给所有者而不是用户对象来轻松解决此问题。

将此类对象传递给 JSON.stringify() 会导致'Converting circular structure to JSON Error'

让我们举个例子,尝试解决这个问题。

例子:

Javascript
var object = {};
object.array = {'first':1};
object.array2 = object;
  
console.log(object);


Javascript
var object = {};
object.array = {'first':1};
object.array2 = object;
  
const circularReplacer = () => {
  
    // Creating new WeakSet to keep 
    // track of previously seen objects
    const seen = new WeakSet();
      
    return (key, value) => {
  
        // If type of value is an 
        // object or value is null
        if (typeof(value) === "object" 
                   && value !== null) {
          
        // If it has been seen before
        if (seen.has(value)) {
                 return;
             }
               
             // Add current value to the set
             seen.add(value);
       }
         
       // return the value
       return value;
   };
};
  
var jsonString = JSON.stringify(
         object, circularReplacer());
console.log(jsonString);


Javascript
var object = {};
object.array = {'first':1};
object.array2 = object;
object.array3 = object.array2;
  
const circularReplacer = () => {
  
    // Creating new WeakSet to keep 
    // track of previously seen objects
    const seen = new WeakSet();
      
    return (key, value) => {
  
        // If type of value is an 
        // object or value is null
        if (typeof(value) === "object" 
                  && value !== null) {
          
        // If it has been seen before
        if (seen.has(value)) {
                 return 'Object';
             }
               
             // Add current value to the set
             seen.add(value);
       }
         
       // return the value
       return value;
   };
};
  
var jsonString = JSON.stringify(
       object, circularReplacer());
console.log(jsonString);


输出 应该是这样的:

如果我们将上述对象传递给 JSON.stringify() 那么这将导致以下错误:

为了解决这个问题,我们可以将另一个参数传递给 JSON.stringify() 这实际上是一个函数。我们可以在函数内部随意处理对象。它有两个参数,键和被字符串化的值。它被字符串化的对象或数组上的每个属性调用。它应该返回应该添加到 JSON字符串的值。

让我们创建一个名为 circularReplacer 的函数。

const circularReplacer = () => {

    // Creating new WeakSet to keep 
    // track of previously seen objects
    const seen = new WeakSet();
    
    return (key, value) => {
        // If type of value is an 
        // object or value is null
        if (typeof(value) === "object" 
            && value !== null) {
        
        // If it has been seen before
        if (seen.has(value)) {
                 return;
             }
             
             // Add current value to the set
             seen.add(value);
       }
       
       // return the value
       return value;
   };
};

解释:

  • 上面的函数将首先创建一个 WeakSet 来跟踪以前看到的对象。 JavaScript 中的 WeakSet 用于存储对象的集合。它适应集合的相同属性,即不存储重复项。在此处阅读 WeakSet 上方的更多信息。
  • 检查值的类型是否为对象且值不为空。然后检查它是否以前见过。如果是,那么就返回。如果没有,则将其添加到集合中。
  • 而不是在看到对象时什么也不返回。我们可以返回更多有用的信息,例如,return 'Object',它将告诉我们 this 的值将创建一个循环结构。
  • 如果值的类型不是对象或值为空。然后简单地返回值。

示例 1:

Javascript

var object = {};
object.array = {'first':1};
object.array2 = object;
  
const circularReplacer = () => {
  
    // Creating new WeakSet to keep 
    // track of previously seen objects
    const seen = new WeakSet();
      
    return (key, value) => {
  
        // If type of value is an 
        // object or value is null
        if (typeof(value) === "object" 
                   && value !== null) {
          
        // If it has been seen before
        if (seen.has(value)) {
                 return;
             }
               
             // Add current value to the set
             seen.add(value);
       }
         
       // return the value
       return value;
   };
};
  
var jsonString = JSON.stringify(
         object, circularReplacer());
console.log(jsonString);

输出:

注意:如果我们只是在看到循环结构时返回,则该键不会被添加到输出字符串中。

示例 2:让我们返回一个字符串,而不是什么都没有。

Javascript

var object = {};
object.array = {'first':1};
object.array2 = object;
object.array3 = object.array2;
  
const circularReplacer = () => {
  
    // Creating new WeakSet to keep 
    // track of previously seen objects
    const seen = new WeakSet();
      
    return (key, value) => {
  
        // If type of value is an 
        // object or value is null
        if (typeof(value) === "object" 
                  && value !== null) {
          
        // If it has been seen before
        if (seen.has(value)) {
                 return 'Object';
             }
               
             // Add current value to the set
             seen.add(value);
       }
         
       // return the value
       return value;
   };
};
  
var jsonString = JSON.stringify(
       object, circularReplacer());
console.log(jsonString);

输出: