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

۱- Optional Chaining (?.)

اولین ویژگی کاربردی در جاوااسکریپت Optional Chaining است. اگر تا به حال برای بررسی مقادیر موجود در یک آبجکت تودرتو چندین عبارت if نوشته باشیم متوجه می‌شویم که Optional Chaining این فرآیند را ساده‌تر کرده و احتمال بروز خطاهای زمان اجرا، هنگام دسترسی به ویژگی‌های عمیق تودرتو را کاهش می‌دهد. به عنوان مثال:

const user = {
  name: 'John',
  address: {
    city: 'New York'
  }
};

// Without Optional Chaining
const city = user && user.address ? user.address.city : undefined;

// With Optional Chaining
const city = user?.address?.city;

console.log(city); // 'New York'

چرا باید از Optional Chaining استفاده کنیم؟

۲- عملگر Nullish Coalescing (??)

عملگر ?? یک جایگزین عالی برای || در ارائه مقادیر پیش‌فرض است. برخلاف || که هر مقدار false مانند false، ۰ یا '' (رشته خالی) را به عنوان مقدار nullish در نظر می‌گیرد، عملگر ?? تنها null و undefined را به عنوان nullish در نظر می‌گیرد. این ویژگی باعث می‌شود تا از اشتباهاتی که ممکن است در استفاده از || اتفاق بیفتد، جلوگیری کنیم. مثلا:

const input = 0;

// Using OR (||)
const value = input || 10; // 10 (undesirable)

// Using Nullish Coalescing (??)
const value = input ?? 10; // 0 (desirable)

console.log(value);

چرا باید از عملگر ?? استفاده کنیم؟

۳- Importهای داینامیک

 Importهای داینامیک به ما این امکان را می‌دهند تا ماژول‌های جاوااسکریپت را به طور مشروط یا در صورت نیاز لود کنیم. این ویژگی به‌ویژه برای بهبود عملکرد در برنامه‌های بزرگ مفید است، زیرا می‌توانیم کد را به بخش‌های کوچک‌تر تقسیم کرده و فقط زمانی که به آن‌ها نیاز داریم، لود نماییم. به عنوان مثال:

if (user.isAdmin) {
  import('./adminPanel.js').then(module => {
    module.loadAdminPanel();
  });
}

چرا باید از Importهای داینامیک استفاده کنیم؟

۴- Promise.allSettled

وقتی با چندین promise در جاوااسکریپت کار می‌کنیم، گاهی ممکن است بخواهیم نتیجه هر promise را، فارغ از موفقیت‌آمیز بودن یا نبودن آن بدانیم. در حالی که Promise.all با اولین reject شدن یکی از promiseها متوقف می‌شود (یعنی سریع شکست می‌خورد)، اما Promise.allSettled حتی اگر یکی از promiseها reject شود، همچنان منتظر تکمیل تمام promiseهای باقی‌مانده می‌ماند و سپس نتیجه کامل را به ما ارائه می‌دهد. به این ترتیب، می‌توانیم وضعیت هر promise (چه موفقیت‌آمیز و چه با خطا) را بررسی نماییم. به عنوان مثال:

const promises = [
  Promise.resolve('Success'),
  Promise.reject('Error'),
  Promise.resolve('Another success')
];

Promise.allSettled(promises).then(results => {
  results.forEach(result => {
    if (result.status === 'fulfilled') {
      console.log('Fulfilled:', result.value);
    } else {
      console.log('Rejected:', result.reason);
    }
  });
});

چرا باید از Promise.allSettled استفاده کنیم؟

عملگرهای تخصیص منطقی (&&=، ||=، ??=)

این عملگرهای کوتاه، عملیات منطقی و انتساب‌ها را ترکیب کرده و کد ما را مختصرتر می‌کنند. به عنوان مثال:

let user = {
  isLoggedIn: false,
  preferences: null
};

// Using Logical Assignment Operators
user.isLoggedIn ||= true; // Sets to true if false or undefined
user.preferences ??= { theme: 'dark' }; // Sets if null or undefined

console.log(user);
// { isLoggedIn: true, preferences: { theme: 'dark' } }

چرا باید از عملگرهای (&&=، ||=، ??=) استفاده کنیم؟

جمع‌بندی

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