如何使用 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);
输出: