رفتن به مطلب
  • زمان مطالعه : 5 دقیقه

اگر توسعه‌دهنده وب باشید یا به دنیای برنامه‌نویسی جاوا اسکریپت علاقه داشته باشید، احتمالاً با چالش‌هایی مثل خطای undefined یا null هنگام دسترسی به خواص یک شیء مواجه شده‌اید. این مشکل معمولاً زمانی رخ می‌دهد که بخواهید به یک ویژگی عمیق در یک شیء دسترسی پیدا کنید، اما مطمئن نباشید که تمام زنجیره مسیر دسترسی به آن ویژگی وجود دارد یا نه. خوشبختانه، جاوا اسکریپت با معرفی Optional Chaining یا زنجیره اختیاری در نسخه ES11 (سال 2020) این مشکل را به شکلی زیبا و کارآمد حل کرده است. در این مقاله قصد دارم شما را با این قابلیت جدید، نحوه کارکرد آن، کاربردهایش و تأثیرش بر کدنویسی روزمره آشنا کنم.

زنجیره اختیاری چیست؟

زنجیره اختیاری که با عملگر ?. نشان داده می‌شود، به شما اجازه می‌دهد به خواص یا متدهای یک شیء دسترسی پیدا کنید، بدون اینکه نگران باشید که آیا مقدار آن شیء یا بخشی از زنجیره مسیرش null یا undefined است یا نه. اگر در هر مرحله از زنجیره، مقدار null یا undefined پیدا شود، به جای پرتاب خطا، به سادگی مقدار undefined برگردانده می‌شود. این ویژگی نه تنها کدنویسی را تمیزتر می‌کند، بلکه از بسیاری از خطاهای رایج که توسعه‌دهندگان با آن دست‌وپنجه نرم می‌کنند، جلوگیری می‌کند.

بیایید با یک مثال ساده شروع کنیم. فرض کنید یک شیء به شکل زیر دارید:

const user = {
  name: "علی",
  address: {
    city: "تهران"
  }
};

حالا اگر بخواهید به user.address.city دسترسی پیدا کنید، مشکلی نیست چون مسیر کامل وجود دارد. اما اگر شیء address وجود نداشته باشد چه؟ مثلاً:

const user = {
  name: "علی"
};

console.log(user.address.city); // TypeError: Cannot read property 'city' of undefined

در این حالت، چون address وجود ندارد، جاوا اسکریپت نمی‌تواند به city دسترسی پیدا کند و خطای TypeError پرتاب می‌شود. قبل از معرفی زنجیره اختیاری، توسعه‌دهندگان مجبور بودند با شرط‌های متعدد این مشکل را مدیریت کنند:

const city = user && user.address && user.address.city;
console.log(city); // undefined

این روش کار می‌کند، اما کد را شلوغ و خواندنش را سخت‌تر می‌کند. حالا با زنجیره اختیاری، همین کار را می‌توان به این شکل انجام داد:

const city = user?.address?.city;
console.log(city); // undefined

خیلی ساده‌تر و خواناتر، نه؟

نحو و نحوه کارکرد

عملگر ?. در سه موقعیت اصلی استفاده می‌شود:

  1. دسترسی به خواص شیء: مثل obj?.prop

  2. دسترسی به آرایه‌ها: مثل arr?.[index]

  3. فراخوانی متدها: مثل obj?.method()

هر وقت از این عملگر استفاده می‌کنید، جاوا اسکریپت ابتدا بررسی می‌کند که مقدار سمت چپ ?. آیا null یا undefined است یا نه. اگر باشد، فرآیند متوقف می‌شود و undefined برمی‌گرداند. اگر نه، به دسترسی یا فراخوانی ادامه می‌دهد.

مثال دیگر برای آرایه‌ها:

const data = [1, 2, 3];
console.log(data?.[1]); // 2

const emptyData = null;
console.log(emptyData?.[1]); // undefined

یا برای متدها:

const user = {
  sayHello() {
    return "سلام!";
  }
};

console.log(user?.sayHello?.()); // "سلام!"
console.log(null?.sayHello?.()); // undefined

چرا زنجیره اختیاری مهم است؟

حالا که با نحوه کارش آشنا شدید، بیایید ببینیم چرا این قابلیت اینقدر مورد استقبال قرار گرفته است:

  1. کاهش خطاها: دیگر نیازی نیست نگران خطاهای غیرمنتظره باشید. اگر داده‌ای که از API یا منبع خارجی می‌آید ناقص باشد، زنجیره اختیاری به شما کمک می‌کند بدون دردسر از آن عبور کنید.

  2. کد تمیزتر: به جای نوشتن شرط‌های طولانی و پیچیده، با یک عملگر ساده می‌توانید همان نتیجه را بگیرید. این یعنی خوانایی بیشتر و نگهداری آسان‌تر.

  3. انعطاف‌پذیری با داده‌های پویا: در دنیای واقعی، داده‌ها همیشه طبق انتظار ما نیستند. مثلاً وقتی با یک API کار می‌کنید، ممکن است بعضی فیلدها گاهی وجود داشته باشند و گاهی نه. زنجیره اختیاری این عدم قطعیت را به خوبی مدیریت می‌کند.

  4. سازگاری با فریم‌ورک‌ها: در کتابخانه‌هایی مثل React یا Vue که با داده‌های پویا زیاد سر و کار دارید، این قابلیت به شدت زمان توسعه را کاهش می‌دهد.

کاربردهای عملی

بیایید چند سناریوی واقعی را بررسی کنیم که زنجیره اختیاری در آن‌ها می‌درخشد:

1. کار با API‌ها

فرض کنید از یک API اطلاعاتی درباره کاربر دریافت می‌کنید:

fetch("https://api.example.com/user")
  .then((response) => response.json())
  .then((data) => {
    const street = data?.user?.address?.street || "خیابان نامشخص";
    console.log(street);
  });

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

2. مدیریت تنظیمات اختیاری

تصور کنید یک تابع دارید که تنظیماتی را به صورت اختیاری می‌پذیرد:

function configure(options) {
  const timeout = options?.timeout ?? 5000; // اگر timeout نباشد، 5000
  console.log(`تنظیم زمان: ${timeout} میلی‌ثانیه`);
}

configure({ timeout: 3000 }); // "تنظیم زمان: 3000 میلی‌ثانیه"
configure({}); // "تنظیم زمان: 5000 میلی‌ثانیه"

اینجا از عملگر ?? (Nullish Coalescing) هم کنار ?. استفاده شده که فقط در صورت null یا undefined مقدار پیش‌فرض را برمی‌گرداند.

3. بررسی توابع اختیاری

اگر بخواهید متدی را فراخوانی کنید که ممکن است وجود نداشته باشد:

const plugin = {
  init: () => console.log("شروع شد!")
};

plugin?.init?.(); // "شروع شد!"
const noPlugin = null;
noPlugin?.init?.(); // هیچ خطایی نمی‌دهد، فقط undefined

محدودیت‌ها و نکات مهم

هرچند زنجیره اختیاری فوق‌العاده است، اما محدودیت‌هایی هم دارد که باید به آن‌ها توجه کنید:

  • پشتیبانی مرورگر: این قابلیت در مرورگرهای قدیمی (مثل IE) پشتیبانی نمی‌شود. اگر پروژه‌تان نیاز به سازگاری با مرورگرهای قدیمی دارد، باید از ابزارهایی مثل Babel استفاده کنید.

  • استفاده بیش از حد: اگر در هر خط کد از ?. استفاده کنید، ممکن است کدتان بیش از حد دفاعی شود و اشکال‌زدایی سخت‌تر شود.

  • تفاوت با عملگرهای دیگر: ?. با && یا || فرق دارد. مثلاً 0 && "something" مقدار 0 را برمی‌گرداند، اما 0?.something خطا نمی‌دهد و undefined می‌دهد.

جمع‌بندی

زنجیره اختیاری (?.) یکی از بهترین قابلیت‌هایی است که جاوا اسکریپت در سال‌های اخیر به خودش دیده است. این ویژگی نه تنها زندگی توسعه‌دهندگان را آسان‌تر کرده، بلکه به ما اجازه می‌دهد کدهایی بنویسیم که هم ایمن‌ترند و هم خواناتر. اگر هنوز از این قابلیت استفاده نکرده‌اید، پیشنهاد می‌کنم همین حالا آن را در پروژه بعدی‌تان امتحان کنید. مطمئنم بعد از چند بار استفاده، دیگر نمی‌توانید بدون آن کدنویسی کنید!

نظر شما چیست؟ آیا تجربه‌ای با زنجیره اختیاری دارید؟ در بخش نظرات وبلاگم برام بنویسید و اگر سوالی دارید، خوشحال می‌شم کمکتون کنم!

بازخورد کاربر

دیدگاه‌های پیشنهاد شده

هیچ دیدگاهی برای نمایش وجود دارد.

دیدگاه خود را ارسال کنید

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

مهمان
افزودن دیدگاه...