بررسی JSON در جاوااسکریپت

درود دوستان! خیلی وقت‌ها اطلاعاتی توی برنامه داریم که می‌خوایم توی برنامه‌های دیگه در دسترس باشه. مثلاً آبجکت user رو در نظر بگیرید که شامل اطلاعاتی از کاربر هست:

const user = {
  name: 'Emily',
  age: 4,
  favorites: ['Reading', 'Walking'],
};

حالا می‌خوایم این اطلاعات رو به یک برنامه دیگه (مثلاً برنامه سمتِ سرور که با PHP نوشته شده) ارسال و اونجا اون رو بررسی کنیم. اما فرمت و نحوه نوشتن این آبجکت برای بقیه زبان‌ها ناشناخته هست. برای مثال چنین آبجکتی توی PHP تقریباً به این صورت نوشته میشه:

$user = [
  &quotname&quot => &quotEmily&quot,
  &quotage&quot => 4,
  &quotfavorites&quot => [&quotReading&quot, &quotWalking&quot],
];

خب ما چطوری می‌تونیم اطلاعاتی داشته باشیم که توی همه زبان‌ها خوانا باشه؟ باید یک فرمت استاندارد وجود داشته باشه که برای همه زبان‌ها شناخته شده و خوانا باشه. جواب، فرمت JSON هست ?

توی این قسمت می‌خوایم یاد بگیریم که:

  • جی‌سان (JSON) چیه؟
  • جی‌سان چه شکلیه؟
  • چطوری اطلاعات رو به جی‌سان تبدیل کنیم؟
  • چه نوع‌های داده‌ای رو میشه به جی‌سان تبدیل کنیم؟
  • چطوری رشتهٔ جی‌سان رو تفسیر کنیم؟
  • آبجکت‌ها و تبدیل به جی‌سان به‌صورت دلخواه




جی‌سان (JSON) چیه؟ ?

JSON (جی‌سان) یک فرمت استاندارد برای تبادل اطلاعات هست. هر چند این تبادل اطلاعات معمولاً از یک زبان به یک زبان دیگه هست، فرمت جی‌سان طوری هست که برای انسان هم خوانا باشه.

JSON مخفف JavaScript Object Notation هست. این فرمت به صورت یک رشتهٔ متنی هست که از ساختار جاوااسکریپت به ارث برده شده و به همین دلیل ساختار اون شباهت زیادی به آبجکت‌های جاوااسکریپتی داره. اما در حال حاضر کاملاً مستقل از جاوااسکریپت هست و تقریباً همه زبان‌های برنامه‌نویسی توانایی کار با فرمت جی‌سان رو دارن. جی‌سان به دلیل حالت رشته‌ای بودنش تقریباً قابل انتقال به هر زبانی هست.



جی‌سان چه شکلیه؟

رشتهٔ زیر یک رشتهٔ جی‌سان هست:

{&quotname&quot:&quotEmily&quot}

همونطور که احتمالاً تشخیص دادین، این حالت رشته‌ای یک آبجکت هست که یک پراپرتی به اسم name داره با مقدار Emily. اما خب توی یک برنامه معمولاً با رشته‌های جی‌سان پیچیده‌تری سر و کار داریم.



چطوری اطلاعات رو به جی‌سان تبدیل کنیم؟

هر زبانی روش خاص خودش رو برای کار با رشته‌های جی‌سان داره. توی جاوااسکریپت ما یک آبجکت سراسری داریم به اسم JSON. این آبجکت که همه جای برنامه در دسترس هست، یک متد داره به اسم stringify که با اون می‌تونیم اطلاعاتمون رو به جی‌سان تبدیل کنیم.

توی کد زیر می‌خوایم آبجکت user رو به رشتهٔ جی‌سان تبدیل کنیم:

const user = {
  name: 'Emily',
  age: 4,
  favorites: ['Reading', 'Walking'],
};

const formattedUser = JSON.stringify(user);

alert(formattedUser);
// {&quotname&quot:&quotEmily&quot,&quotage&quot:4,&quotfavorites&quot:[&quotReading&quot,&quotWalking&quot]}

الان آبجکت user تونست به فرمتی تبدیل بشه که قابل تبادل با بقیه زبان‌ها و برنامه‌ها باشه. بقیه زبان‌ها راحت می‌تونن اون رو تفسیر و بررسی کنن.

ورودی متد stringify باید یک نوع داده‌ای معتبر جاوااسکریپتی باشه. وقتی اطلاعاتی رو به حالت جی‌سان تبدیل می‌کنیم، به اصطلاح می‌گیم اطلاعات رو سریالایز (Serialize) کردیم. رشته‌های جی‌سان معمولاً توسط برنامه تولید میشه. یعنی خیلی کم اتفاق میوفته که یک برنامه‌نویس بخواد به صورت دستی یک رشتهٔ جی‌سان بنویسه.




چه نوع‌های داده‌ای رو میشه به جی‌سان تبدیل کنیم؟

همونطور که می‌دونیم توی جاوااسکریپت نوع‌های داده‌ای مختلفی داریم. بعضی از این نوع‌ها به شکل‌های مختلفی توی رشته‌های جی‌سان قرار می‌گیرن و بعضی‌ها کلاً قابلیت قرار گرفتن توی رشته‌های جی‌سان رو ندارن.

نوع‌های داده‌ای بولین، عدد، رشته، نال و آبجکت می‌تونن توی یک رشتهٔ جی‌سان قرار بگیرن. یعنی برای مثال اگه آرایه‌ای داشته باشیم که شامل چنین نوع‌های داده‌ای باشه، با تبدیل آرایه به جی‌سان، همگی رو می‌تونیم توی خروجی ببینیم:

const types = [
  &quothello&quot,            // string
  29,                 // number
  false,              // boolean
  { name: &quotEmily&quot },  // object
  null,               // null
];

const serialized = JSON.stringify(types);

alert(serialized); // [&quotstring&quot,29,false,{&quotname&quot:&quotEmily&quot},null]

اما بعضی از نوع‌های داده‌ای مثل undefined و توابع قابلیت قرار گرفتن توی رشته‌های جی‌سان رو ندارن. بر این اساس وقتی یک آبجکت رو به جی‌سان تبدیل می‌کنیم متدهای اون و همچنین پراپرتی‌هایی که مقدار اونها undefined هست نادیده گرفته میشن. همچنین مقدار پراپرتی که NaN باشه null در نظر گرفته میشه:

const user = {
  name: &quotMario&quot,
  favorites: undefined,
  age: NaN,
  talk() {

  }
}

const serialized = JSON.stringify(user);

alert(serialized); // {&quotname&quot:&quotMario&quot,&quotage&quot:null}

اگه چنین نوع‌های داده‌ای توی یک آرایه قرار بگیرن تبدیل به null میشن:

const array = [&quotstring&quot, () => {}, undefined, NaN];

alert(JSON.stringify(array)); // [&quotstring&quot,null,null,null]




چطوری رشتهٔ جی‌سان رو تفسیر کنیم؟

فرض کنیم اطلاعاتی به صورت یک رشتهٔ جی‌سان به سمت برنامه اومده:

const input = '{&quotname&quot:&quotEmily&quot,&quotage&quot:4,&quotfavorites&quot:[&quotReading&quot,&quotWalking&quot]}';

الان مقدار متغیر input یک رشتهٔ جی‌سان هست. برای اینکه بتونیم با اون کار کنیم ابتدا باید اون رو تفسیر کنیم. ما این کار رو با متد parse از آبجکت JSON انجام می‌دیم:

const input = '{&quotname&quot:&quotEmily&quot,&quotage&quot:4,&quotfavorites&quot:[&quotReading&quot, &quotWalking&quot]}';

const user = JSON.parse(input);

console.log(user);
alert(user.name);      // Emily
alert(user.favorites); // Reading, Walking

با اجرای کد می‌بینیم که یک آبجکت معتبر جاوااسکریپتی به ما نمایش داده میشه. وقتی یک رشته جی‌سان رو به نوع قابل فهم برای جاوااسکریپت تبدیل کردیم، به اصطلاح می‌گیم رشته رو آنــــسِریالایز (Unserialize) کردیم.

ورودی متد parse باید یک رشتهٔ معتبر جی‌سان باشه. در غیر این صورت خطا می‌گیریم.


توی کد زیر بعضی از کارکترهای رشتهٔ جی‌سان به عمد حذف شده:

const input = '{&quotname&quot:&quotEmily&quot,&quotage&quot:4,&quotfavorites&quot:[&quotReading]';

JSON.parse(input); // SyntaxError: JSON.parse:
                   // unterminated string at line 1 column 47
                   // of the JSON data

با اجرای کد می‌بینیم که جاوااسکریپت با خطا میگه نمی‌تونم این رشته رو تفسیر کنم.




آبجکت‌ها و تبدیل به جی‌سان به‌صورت دلخواه

اگه می‌خوایم به صورت شخصی‌سازی شده یک آبجکت رو تبدیل به جی‌سان کنیم، مثلاً توی آبجکت پراپرتی‌هایی داریم که نمی‌خوایم توی حالت جی‌سان حضور داشته باشن، باید توی آبجکت یک متد تعریف کنیم به اسم toJSON. این متد مسئول فراهم آوردن چیزهایی هست که می‌خوایم توی جی‌سان وجود داشته باشه:

const user = {
  name: &quotMario&quot,
  password: &quotxx-cat-xx&quot,
  
  toJSON(){
    const _this = this;

    return {
      name: _this.name,
      age: 4,
    }
  }
}

const serialized = JSON.stringify(user);

alert(serialized); // {&quotname&quot:&quotMario&quot,&quotage&quot:4}

در واقع هر چیزی که توسط متد toJSON ریترن (Return) بشه توی خروجی قرار می‌گیره. ما توی این متد یک آبجکت دلخواه دیگه رو ریترن کردیم.



خب دوستان این همه چیزهایی بود که باید از جی‌سان می‌دونستیم. توی یک برنامهٔ جاوااسکریپتی خیلی زیاد با جی‌سان سر و کار داریم. روزتون خوش. تا قسمت بعدی ?✌️


Resources:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

https://www.json.org/json-en.html

https://ditty.ir/