جاوااسکریپت: شیء انتخاب‌ها (options objects) چیست؟

در جاوااسکریپت، اشیاء ِ انتخاب‌ها (که از این پس به آن‌ها options objects می‌گوییم) یک الگوی ِ معمول برای ِ فرستادن ِ آرگومان‌ها به یک تابع هستند. این مقاله به شرح ِ چگونگی ِ کار ِ آن‌ها و نیز دلیل ِ این که استفاده از آن‌ها باعث ِ افزایش ِ خوانایی ِ کد ِ شما می‌شود، می‌پردازد.

options object چیست؟

یک options object یک شیء ِ معمولی ِ جاوااسکریپت است، که داخل ِ آن‌ مجموعه‌ای از پارامتر‌هایی با اسم‌های ِ مشخص تعریف شده و به عنوان ورودی به یک تابع فرستاده می‌شود.

برای ِ مثال، تابع ِ jQuery.ajax از options object استفاده می‌کند. این تابع می‌تواند تا ۳۴ پارامتر ِ مختلف را بگیرد که تمام ِ آن‌ها اختیاری هستند.

$.ajax({
    url: "http://date.jsontest.com/",
    success: function (data) {console.log(data);},
    cache: true,
    timeout: 500
});

بدون ِ استفاده از یک options object فهم ِ این که هر پارامتر برای ِ چه کاری است، بسیار سخت خواهد بود:

$.ajax(
    "http://date.jsontest.com/",
    function (data) {console.log(data);},
    true,
    500
);

بسیاری دیگر از زبان‌های برنامه‌نویسی، امکانی دارند تحت ِ نام ِ «آرگومان‌های اسم‌دار» (به انگلیسی: named arguments) که کارایی ِ مشابهی با options objects دارند.

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

زمانی که تابعی حداقل دو یا بیشتر آرگومان داشته باشد، می‌توان استفاده از options object را مد ِ نظر قرار داد. برای تابعی که چهار یا بیشتر آرگومان دارد، استفاده از options object معمولاً ایده‌ی خوبی است.

اگر تابعی فعلا یک آرگومان بیشتر ندارد، اما حدس می‌زنید که بعدا نیاز خواهد شد تا آرگومان‌های بیشتری به آن اضافه کنید، از همان ابتدا از options object استفاده کنید تا نیاز نباشد بعدا کد‌های خود را از نو بنویسید.

در نهایت آنچه که تعیین کننده‌ی این است که آیا options object گزینه‌ی بهتری است یا لیست آرگومان‌ها (یعنی همان روش ِ معمول برای ِ دادن ِ ورودی به توابع)، این است که آیا پاسخ به پرسش ِ «آرگومان‌ها برای چه هستند» واضح است یا نه. برای مثال ورودی‌های تابع (sum(4, 2 به قدر  ِ کافی گویا هستند، اما چیزی مثل (showDialog(true , false خیر.

نوشتن ِ یک تابع که ورودی ِ آن یک options object است

در زیر یک تابع را مشاهده می‌کنید که به روش ِ سنتی ِ گرفتن ِ آرگومان‌ها به صورتِ جدا جدا، نوشته شده است:

function showDialog (showAlertIcon, showBackdrop) {
    if (showAlertIcon) {
        alertIcon.show();
    }
    if (showDarkBackdrop) {
        backdrop.show();
    }
    dialog.show();
}

و در ادامه نحوه‌ی فراخوانی ِ آن:

showDialog(true, false);

خط ِ بالا به وضوح مشخص نمی‌کند که هر آرگومان برای چه کاری است. این مشکل با از نو نوشتن ِ تابع، به صورتی که یک options object را به عنوان ِ ورودی بگیرد، حل می‌شود:

function showDialog (options) {
    if (options.showAlertIcon) {
        alertIcon.show();
    }
    if (options.showDarkBackdrop) {
        backdrop.show();
    }
    dialog.show();
}

حال، showDialog می‌تواند با یک شیء به عنوان ِ ورودی فراخوانی شود؛ که در آن شیء به ازای ِ هر پارامتر، یک جفت ِ کلید/مقدار (به انگلیسی: key/value) وجود دارد:

showDialog({
    showAlertIcon: true,
    showDarkBackdrop: false
});

با این روش، به روشنی مشخص است که هر پارامتر ِ تابع برای چه کاری است و نیازی به نگاه انداختن به تعریف ِ تابع، برای ِ درک ِ نحوه‌ی ِ فراخوانی ِ تابع نیست.

تنظیم مقادیر اولیه

options objectها همچنین امکان ِ اختیاری کردن ِ یک پارامتر را به راحتی می‌دهند. زمانیکه یک پارامتر ِ اختیاری، مقداردهی نشده، یک مقدار ِ اولیه باید جای ِ آن را بگیرد.

کتابخانه‌ی Underscore متدی با نام ِ defaults._ دارد که options object داده شده را مستقیما تغییر می‌دهد؛ بنابراین بهتر است برای ِ عدم ِ پیش‌آمدن ِ نتایج ناخواسته، از استفاده از این متد به طور ِ مستقیم خودداری کنید.

به جای ِ آن می‌توانید یک تابع ِ مخصوص ِ خودتان بنویسید:

function setDefaults(options, defaults){
    return _.defaults({}, _.clone(options), defaults);
}

تابع ِ setDefaults یک کپی از آرگومان ِ options که به آن داده شده، می‌سازد؛ که با این کار تضمین می‌کند که options object اصلی بدون ِ تغییر خواهد‌ماند.

حالا می‌توانید از setDefaults برای ِ مقداری‌دهی ِ اولیه‌ی پارامتر ِ داده شده به تابعتان استفاده‌کنید.

 function showDialog (options) {
      var defaults = {
          showAlertIcon: false,
          showDarkBackdrop: true
      };
      options = setDefaults(options, defaults);
      if (options.showAlertIcon) {
          alertIcon.show();
      }
      if (options.showDarkBackdrop) {
          backdrop.show();
      }
      dialog.show();
  }

بعد از این تغییر می‌توانید تابع ِ showDialog را تنها با پارامتر‌هایی که می‌خواهید صدابزنید:

 showDialog({showDarkBackdrop: false});


منبع: http://www.codereadability.com/what-are-javascript-options-objects/

نوشته‌ی اصلی: http://mahdavipanah.com/blog/js-options-object/