از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
چاپ ساختارهای دایره ای با فرمت JSON در جاوا اسکریپت سروکار داشتن با ساختارهای داده در جاوا اسکریپت گاهی اوقات می تواند مشکل باشد، به خصوص زمانی که با مواردی مانند ساختارهای دایره ای مواجه می شویم. در این مقاله، بررسی خواهیم کرد که ساختارهای دایرهای چیست، چرا وقتی میخواهیم آنها را در قالب JSON چاپ کنیم، چالشهایی ایجاد میکنند، و چگونه میتوانیم این کار را انجام دهیم…
سرفصلهای مطلب
معرفی
سر و کار داشتن با ساختارهای داده در جاوا اسکریپت گاهی اوقات می تواند مشکل باشد، به خصوص زمانی که با مواردی مانند ساختارهای دایره ای مواجه می شویم. در این مقاله، بررسی خواهیم کرد که ساختارهای دایرهای چیست، چرا وقتی میخواهیم آنها را در قالب JSON چاپ کنیم، چالشهایی ایجاد میکنند، و چگونه میتوانیم این کار را برای مورد استفاده خود انجام دهیم.
ساختارهای دایره ای در جاوا اسکریپت
در جاوا اسکریپت، ساختار دایرهای به شیئی گفته میشود که مستقیم یا غیرمستقیم به خود ارجاع میدهد. این به این معنی است که ویژگی یک شی به شیء باز می گردد و یک حلقه یا “دایره” از مراجع تشکیل می دهد. در اینجا یک مثال ساده آورده شده است:
let circularObject = {};
circularObject.myself = circularObject;
در این مثال، circularObject
یک ساختار دایره ای است زیرا myself
ملک اشاره به circularObject
خود
ساختارهای دایرهای نیز میتوانند پیچیدهتر باشند، با اشیاء تو در تو که در نهایت به شی والد ارجاع میدهند، یا حتی آرایههایی که یک عنصر به آرایه برمیگردد.
let circularObject = {
child: {
parent: circularObject
}
};
let circularArray = (1, 2, 3);
circularArray.push(circularArray);
در مثال اول، parent
دارایی از child
شی به بازگشت اشاره دارد circularObject
. در مثال دوم اضافه می کنیم circularArray
به عنوان عنصری از خود
در حالی که ساختارهای دایره ای ممکن است در سناریوهای خاصی مفید باشند، اما زمانی که بخواهیم آنها را به فرمت رشته ای مانند JSON تبدیل کنیم، مشکل ایجاد می کنند. در بخشهای بعدی، بررسی خواهیم کرد که چرا چنین است و چگونه میتوانیم ساختارهای دایرهای را در قالب JSON مانند چاپ کنیم.
چرا JSON.stringify() با ساختارهای دایره ای شکست می خورد
متأسفانه، همانطور که خواهید دید، JSON.stringify()
روش قادر به مدیریت صحیح ساختارهای دایره ای نیست.
چه زمانی JSON.stringify()
با چنین ساختاری مواجه می شود، خطا را ایجاد می کند TypeError: Converting circular structure to JSON
یا TypeError: cyclic object value
. این به این دلیل است که این روش سعی میکند به صورت بازگشتی به ویژگیهای شی دسترسی پیدا کند، اما در مورد ساختار دایرهای، این منجر به یک حلقه بینهایت میشود.
let circularObject = {};
circularObject.myself = circularObject;
try {
JSON.stringify(circularObject);
} catch (e) {
console.error(e.toString());
}
با اجرای این کد خروجی زیر حاصل می شود:
$ node circular.js
TypeError: Converting circular structure to JSON
خطا پرتاب می شود زیرا JSON.stringify()
اساساً سعی در دسترسی دارد circularObject.myself.myself.myself...
(و غیره روی).
چاپ سازه های دایره ای
بنابراین، چگونه می توانیم ساختارهای دایره ای را با فرمت JSON مانند چاپ کنیم؟ خوشبختانه، چند روش وجود دارد که می توانیم برای دور زدن محدودیت ها از آنها استفاده کنیم JSON.stringify()
.
یکی از راه ها استفاده از یک تابع جایگزین سفارشی با JSON.stringify()
. و راه دیگر استفاده از util
بسته ها inspect()
تابع، که در بخشهای بعدی با جزئیات بیشتر به هر دوی آنها خواهیم پرداخت.
استفاده از JSON.stringify() با یک تابع جایگزین سفارشی
هنگامی که با ساختارهای دایره ای در جاوا اسکریپت سروکار داریم، JSON.stringify()
روش می تواند کمی مشکل باشد. همانطور که بحث کردیم، وقتی با یک مرجع دایره ای روبرو می شود، خطا می دهد. با این حال، با استفاده از یک تابع جایگزین سفارشی، یک راه حل ساده برای این کار وجود دارد.
را JSON.stringify()
روش دو پارامتر اضافی را می پذیرد: یک جایگزین و یک فاصله. جایگزین کننده می تواند تابعی باشد که رفتار رشته را تغییر می دهد process، یا آرایه ای از اشیاء String و Number.
در مورد ما، ما از تابعی استفاده خواهیم کرد که اشیایی را که قبلاً سریالسازی کردهایم ردیابی میکند و به ما امکان میدهد تا ارجاعات دایرهای را مدیریت کنیم.
در اینجا یک مثال است:
let cache = ();
let circularObject = {};
circularObject.circularRef = circularObject;
let str = JSON.stringify(circularObject, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (cache.includes(value)) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
cache = null; // Enable garbage collection
console.log(str); // {"circularRef":{}}
در این کد، یک آبجکت دایرهای و یک حافظه پنهان برای پیگیری اشیایی که قبلاً بازدید کردهایم ایجاد کردیم. تابع جایگزین ما بررسی می کند که آیا مقدار فعلی یک شی است و آیا از قبل در حافظه پنهان ما وجود دارد یا خیر. اگر اینطور باشد، یک مرجع دایره ای پیدا کردیم و کلید را دور می اندازیم. در غیر این صورت، شی را به کش خود اضافه می کنیم و مقدار را برمی گردانیم.
توجه داشته باشید: این رویکرد کلیدهای مرتبط با ارجاعات دایرهای را کنار میگذارد، بنابراین JSON حاصل آینه کاملی از شی اصلی نخواهد بود. با این حال، به ما این امکان را می دهد که ساختارهای دایره ای را بدون خطا سریال کنیم.
استفاده از util.inspect()
اگر با Node.js کار می کنید، راه حل ساده تری برای چاپ ساختارهای دایره ای وجود دارد: util.inspect()
روش. این متد یک نمایش رشته ای از یک شی را برمی گرداند، شبیه به JSON.stringify()
، اما ارجاعات دایره ای را به خوبی مدیریت می کند.
در اینجا یک مثال است:
const util = require('util');
let circularObject = {};
circularObject.circularRef = circularObject;
console.log(util.inspect(circularObject));
هنگامی که این کد را اجرا می کنید، چیزی شبیه به این خواهید دید:
{ circularRef: (Circular) }
را (Circular)
مکان نگهدار یک مرجع دایره ای به ریشه شی فعلی را نشان می دهد.
توجه داشته باشید: را util.inspect()
متد یک ویژگی خاص Node.js است و در جاوا اسکریپت سمت مرورگر موجود نیست. برای اشکالزدایی یا ورود به یک محیط Node.js عالی است، اما برای سریالسازی دادههای ارسالی از طریق شبکه مناسب نیست.
یکی از چیزهای بزرگ در مورد util.inspect()
این است که یک شی گزینه را نیز می پذیرد که به شما امکان می دهد خروجی را سفارشی کنید. به عنوان مثال، شما می توانید تنظیم کنید depth
گزینه ای به null
برای بازرسی تمام اشیاء، صرف نظر از عمق.
console.log(util.inspect(circularObject, { depth: null }));
این کار کل شی را چاپ میکند، مهم نیست که ارجاعات دایرهای چقدر عمیق هستند. بنابراین مراقب اشیاء بزرگ و پیچیده باشید – ممکن است خروجی بیشتری از آنچه می خواهید دریافت کنید.
استفاده از کتابخانه های شخص ثالث
در حالی که روشهای بومی جاوا اسکریپت میتوانند تا حدودی به ما کمک کنند تا ساختارهای دایرهای را مدیریت کنیم، سناریوهای خاصی وجود دارد که ممکن است کوتاهی کنند. اینجاست که ما به کتابخانه های شخص ثالث برای کمک نگاه می کنیم. این کتابخانه ها به طور خاص برای مدیریت ساختارهای دایره ای طراحی شده اند و می توانند کار ما را به طور قابل توجهی آسان تر کنند. برخی از کتابخانه های محبوبی که می توانیم از آنها استفاده کنیم، هستند circular-json
و flatted
.
مثال: با استفاده از کتابخانه circular-json
بیایید نگاهی به روش استفاده از آن بیندازیم circular-json کتابخانه برای چاپ ساختارهای دایره ای در قالب JSON مانند. را circular-json
کتابخانه ارائه می کند stringify()
تابع، شبیه به JSON.stringify()
، اما با توانایی اضافه شده برای کنترل ساختارهای دایره ای.
ابتدا باید کتابخانه را نصب کنیم. شما می توانید این کار را با اجرای دستور زیر در خود انجام دهید terminal:
$ npm install circular-json
پس از نصب، میتوانیم آن را در کد خود به صورت زیر استفاده کنیم:
const CircularJSON = require('circular-json');
let circularObject = {};
circularObject.circularRef = circularObject;
let serialized = CircularJSON.stringify(circularObject);
console.log(serialized);
در مثال بالا یک ساختار دایره ای ایجاد می کنیم که در آن circularObject.circularRef
اشاره دارد به circularObject
خود وقتی سعی می کنیم این را با استفاده از سریال سریال کنیم CircularJSON.stringify()
، با موفقیت شی را به قالب رشته ای تبدیل می کند بدون اینکه خطایی ایجاد کند. خروجی چیزی شبیه به این خواهد بود:
{"circularRef":"~"}
همانطور که می بینید، circular-json
کتابخانه مرجع دایره ای را با یک کاراکتر خاص جایگزین می کند (~
) که ساختار دایره ای را نشان می دهد.
سر به بالا: را circular-json
کتابخانه منسوخ شده و دیگر نگهداری نمی شود. با این حال، هنوز برای اکثر موارد استفاده خوب کار می کند و به عنوان مثال خوبی از اینکه چگونه کتابخانه های شخص ثالث می توانند به ما در مدیریت ساختارهای دایره ای در جاوا اسکریپت کمک کنند، عمل می کند. فقط مطمئن شوید که قبل از استفاده از آن در کد تولید، بررسی کنید که آیا آسیبپذیری با شدت بالا باز است یا خیر.
مثال: استفاده از کتابخانه مسطح
یکی از کتابخانه های شخص ثالث که می تواند مراجع دایره ای را در جاوا اسکریپت مدیریت کند، کتابخانه است مسطح شده کتابخانه این کتابخانه یک API ساده شبیه به JSON را ارائه می دهد Flatted.stringify()
و Flatted.parse()
مواد و روش ها. بیایید ببینیم چگونه می توانیم از آن برای چاپ یک ساختار دایره ای استفاده کنیم.
ابتدا باید آن را نصب کنید flatted
کتابخانه می توانید این کار را با استفاده از npm انجام دهید:
$ npm install flatted
پس از نصب، می توانید از آن برای رشته بندی و تجزیه ساختارهای دایره ای استفاده کنید. در اینجا یک مثال است:
const Flatted = require('flatted');
let circularObject = {};
circularObject.self = circularObject;
console.log(Flatted.stringify(circularObject));
این یک رشته با یک نحو خاص که مرجع دایره ای را نشان می دهد خروجی می دهد:
{"self":"$"}
سپس می توانید این رشته را دوباره به یک شی با استفاده از Flatted.parse()
روش:
let parsedObject = Flatted.parse(Flatted.stringify(circularObject));
console.log(parsedObject === parsedObject.self);
این خروجی خواهد شد true
، نشان می دهد که مرجع دایره ای حفظ شده است.
توجه داشته باشید: را flatted
کتابخانه از یک نحو خاص برای نمایش مراجع دایره ای استفاده می کند که ممکن است با دیگر تجزیه کننده های JSON سازگار نباشد. حتما استفاده کنید Flatted.parse()
روشی برای تفسیر صحیح این نحو.
نتیجه
ساختارهای دایره ای می توانند هنگام تلاش برای چاپ یا سریال سازی آنها در جاوا اسکریپت چالشی ایجاد کنند. ساخته شده در JSON.stringify()
روش با ساختارهای دایره ای شکست می خورد، اما می توانیم با استفاده از یک تابع جایگزین سفارشی، بر این محدودیت غلبه کنیم. util.inspect()
روش، یا کتابخانه های شخص ثالث مانند circular-json
و flatted
. این ابزارها راههای مختلفی را برای مدیریت ارجاعات دایرهای ارائه میکنند و به ما امکان میدهند ساختارهای دایرهای را در قالبی شبیه JSON چاپ یا سریال کنیم.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1402-12-30 02:33:05