برنامه‌نویس جاوا اسکریپت، تمیز‌تر کد بزن! نکاتی برای کدنویسی تمیزتر برای برنامه نویسان جاوا اسکریپت
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 7 دقیقه

برنامه‌نویس جاوا اسکریپت، تمیز‌تر کد بزن! نکاتی برای کدنویسی تمیزتر برای برنامه نویسان جاوا اسکریپت

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

به همین دلیل است که برنامه نویسان جاوا اسکریپت باید پایبند به یکسری اصول و قواعد باشند. در این مقاله از وبسایت آموزشی راکت ما شما را با چند نکته برای کدنویسی تمیزتر در جاوا اسکریپت راهنمایی می‌کنیم. باشد که کدهای تمیزتر و مرتب‌تری را بنویسید!

نکته اول: از تودرتوسازی‌های غیر ضروری خودداری کنید

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

برای مثال در بسیاری از مواقع شما بجای استفاده کردن از دستورات if/else می‌توانید بسیار کوتاهتر همه چیز را نوشته و حجم تودرتو نویسی‌های‌تان را کاهش دهید. یا به عنوان یک مثال دیگر به قطعه کد زیر نگاه کنید:

function deleteItem(item) {
  if (item != null) {
    console.log("Deleting item");
    item.delete();
  }
}

خب همانطور که می‌بینید این کد هیچ مشکل عملکردی ندارد اما ما می‌توانیم به یک روش ساده آن را از یک سطح تودرتو نویسی خلاص کنیم. برای اینکار کافی‌ست از تکنیک guard clause استفاده کنیم. در این روش بجای آنکه بررسی Null نبودن را انجام دهیم، ما بررسی می‌کنیم که آیا Null هست؟! که اگر بود به صورت سریع یک مقدار return  شود. در نهایت کدهای دیگر را قرار خواهیم داد. در قطعه کد زیر می‌توانید شاهد نتیجه کار باشید، همان طور که می‌بینید حجم تودرتو نویسی یک سطح کمتر شده است.

function deleteItem(item) {
  if (item == null) return;

  console.log("Deleting item");
  item.delete();
}

بیایید به یک مثال دیگر نگاه بیاندازیم:

function saveItem(item) {
  if (item != null) {
    console.log("Validating");

    if (item.isValid()) {
      console.log("Saving item");
      item.save();
    }
}

خب همانطور که می‌بینید به لحاظ کارکردی این قطعه کد هیچ مشکلی ندارد و همه چیز به درستی کار می‌کند. اما اگر از همان تکنیک guard clause استفاده شود می‌توانید کد مختصرتری مانند زیر را ایجاد کنید:

function saveItem(item) {
  if (item == null) return;

  console.log("Validating");
  if (!item.isValid) return;

  console.log("Saving item");
  item.save();
}

همانطور که مشاهده می‌کنید return کردن بلافاصله بعد از یک دستور if می‌توانید از تودرتو نویسی کمتری استفاده کرده و در نتیجه ساختار واضح‌تری داشته باشید.

نکته دوم: استفاده از Object Destructuring برای پارامتر توابع

فرض کنیم شما یک تابع دارید که به عنوان ورودی یک Object را دریافت کرده و یکسری عملیات را روی این Object برای تولید خروجی انجام می‌دهد. حال بدون استفاده کردن از object destructuring شما در نهایت چیزی شبیه به قطعه کد زیر خواهید داشت.

// not so good
function getFullName(person) {
  const firstName = person.firstName;
  const lastName = person.lastName;
  return `${firstName} ${lastName}`;
}

قطعه کد بالا به درستی کار می‌کند اما همانطور که مشاهده می‌کنید ما دو متغیر یا مرجع موقتی با نام‌های firstName و lastName را داریم که واقعا به آن‌ها نیاز نخواهیم داشت.

یک رویکرد بهتر برای ایجاد چنین قطعه کدی استفاده از object destructuring است. در این حالت ما می‌توانیم بدون استفاده از متغیرها یا مرجع‌های غیر ضروری به صورت مستقیم از خاصیت‌های خود object destructuring استفاده کنیم. به قطعه کد زیر که بهینه‌سازی شده مثال پیش است نگاه کنید:

// better
function getFullName(person) {
  const { firstName, lastName } = person;
  return `${firstname} ${lastName}`;
}

حال حتی می‌توانیم یک قدم به جلوتر رفته و خود پارامتر را نیز تجزیه کنیم. این کار یک خط دیگر از کدهای‌مان را حذف می‌کند:

// even better
function getFullName({ firstName, lastName }) {
  return `${firstName} ${lastName}`;
}

همانطور که مشاهده کردید در این صورت تابع ما به صورت بسیار بهینه‌تر و ساده‌تر نوشته می‌شود.

نکته سوم: اجتناب از تاثیرات جانبی با استفاده کردن از توابع خالص

زمانی که یک تابع را ایجاد می‌کنید بسیار مهم است که این نکته را در نظر داشته: از تغییر هر متغیری خارج از دامنه تابع خودداری کنید:

// bad
let items = 5;
function changeNumber(number) {
  items = number + 3;
  return items;
}
changeNumber(5);

در مثال بالا هر بار که ما تابع changeNumber را فراخوانی کنیم مقدار متغیر items که در خارج از خود تعریف شده را تغییر می‌دهد. همواره به عنوان یک نکته مهم گفته شده که در ساختار ایجاد توابع از انجام دادن چنین کاری به شدت خودداری کنید چرا که منجر به انجام کارهای غیر منتظره خواهد شد. یکی دیگر از مشکلات انجام چنین کاری این است که تابع ما با تکیه بر یک متغیر خارجی در حال انجام کار است: اگر متغیر ما وجود نداشته باشد و یا نوع داده‌ای متفاوتی داشته باشد چه؟ در این صورت کل کارکرد تابع با خطا روبرو می شود.

بنابراین بجای انجام چنین کاری از توابع خالص یا Pure Function استفاده کنید. به مثال زیر دقت کنید:

// good
function addThree(number) {
  return number + 3;
}

همانگونه که مشاهده می‌کنید تابع addThree به هیچ متغیر خارجی وابسته نبوده و هیچ متغیر خارجی را نیز دستکاری نمی‌کند.

نکته چهارم: توابع را ساده نگهدارید

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

function signUpAndValidate() {
// Do a heap of stuff here
}

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

function signUp() {
}
function validate() {
}

نکته پنجم: همواره از اسامی معنادار استفاده کنید

خب کدنویسی در وهله اول ساده به نظر می‌رسد تا زمانی که شما کدهای کس دیگری را مطالعه کنید؛ البته وقتی که یک مدتی از نوشتن کدهای خودتان بگذرد نیز این اتفاق برای خودتان می‌افتد.

یکی از اصلی‌ترین دلایل این موضوع این است که شما از اسامی نامفهوم برای متغیرها و توابع‌تان استفاده می‌کنید. به همین دلیل چند نکته مهمی که در زیر برای نامگذاری متغیرها و توابع آمده را حتما در نظر داشته و به خاطر بسپارید:

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

// bad
function passwordValidation() {
}
// good
function validatePassword() {
}

نکته دوم: زمانی که در حال تعریف یک Boolean هستید از کلمه is استفاده کنید:

const isValidPassword = validatePassword("abcd");

نکته سوم: زمان ایجاد آرایه‌ها و لیست‌ها از نام‌های جمع استفاده کنید (حرف s را در آخر اسامی خود به کار ببرید):

const animal = ["cat", "dog", "bird"]; //bad
const animals = ["cat", "dog", "bird"]; //good

در پایان

رابرت مارتین - عمو باب - نویسنده کتاب کد تمیز

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

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

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
4.6 از 5 رای

/@arastoo
ارسطو عباسی
کارشناس تولید و بهینه‌سازی محتوا

کارشناس ارشد تولید و بهینه‌سازی محتوا و تکنیکال رایتینگ - https://arastoo.net

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید