آموزش جاوا اسکریپت – جلسه ۶ – استایل کدنویسی [Coding Style]
![آموزش جاوا اسکریپت – جلسه 6 – استایل کدنویسی [Coding Style]](https://rahkarino.ir/wp-content/uploads/2020/05/js-part6-coding-style.jpg)
درود بر شما دوستان همراه راهکاری نو. در فصل قبل یعنی فصل پنجم، نحوه دیباگ یا خطایابی کدهای جاوا اسکریپت را در مرورگر گوگل کروم آموزش دادیم. پنل Source و Console را در مرورگرهایی که موتور (engine) آنها کرومیوم است را توضیح دادیم و نحوه پیمایش (trace) خط به خط کدهای js را توسط دستور debugger یا breakpoint آموزش دادیم.
در این مقاله می خواهیم نحوه کدنویسی استاندارد جاوا اسکریپت را آموزش دهیم. با ما همراه باشید.
کدهای جاوا اسکریپت ما باید تا حد ممکن تمیز و به راحتی قابل خوانش باشند. در واقع هنر یک برنامه نویس است که یک مسئله پیچیده را تحویل بگیرد و توسط یک کدنویسی روان و تمیز آن را حل کند.
تعریف کدهای جاوااسکریپت بصورت استاندارد:
در تصویر زیر استاندارد تعریف کدهای جاوااسکریپت را نشان داده ایم:
Curly Braces:
در پروژه های جاوا اسکریپتی، علامت curly brace با استایل Egyptian تعریف می شود. یعنی آکولاد باز در همان خط و با یک فاصله نسبت به کلمه قبل. مثال:
if (condition) { // do this // ...and that // ...and that }
اگر ما یک دستور داشته باشیم (مانند if (condition) doSomething()) آیا نیاز به {} داریم یا خیر؟
در این بخش روش های مختلف تعریف دستورات را می بینیم:
- برخی از برنامه نویسان از آکولاد برای تعریف دستور یک خطی استفاده می کنند (اصلا توصیه نمی شود!). مانند:
if (n < 0) {alert(`Power ${n} is not supported`);}
- برخی ممکن است دستور را در خط بعدی بنویسند و از } { استفاده نکنند. مانند:
if (n < 0) alert(`Power ${n} is not supported`);
- برخی دیگر ممکن است دستور را در یک خط و بدون } { تعریف کنند. مانند:
if (n < 0) alert(`Power ${n} is not supported`);
- و اما بهترین روش (استفاده از } { و تعریف دستور در خط دیگر):
if (n < 0) { alert(`Power ${n} is not supported`); }
نکته: تعریف دستورات کوتاه در یک خط و بدون { } قابل قبول است. مانند: if (cond) return null
طول خط (Line Length):
هیچکس دوست ندارد یک خط طولانی و دراز را بخواند. پس بهتر است مانند زیر، ادامه کد را به سطرهای بعدی منتقل کنیم:
// backtick quotes ` allow to split the string into multiple lines let str = ` ECMA International's TC39 is a group of JavaScript developers, implementers, academics, and more, collaborating with the community to maintain and evolve the definition of JavaScript. `;
و برای دستور if:
if ( id === 123 && moonPhase === 'Waning Gibbous' && zodiacSign === 'Libra' ) { letTheSorceryBegin(); }
تعداد کاراکتر مجاز در هر خط قانونی است که هر تیم برنامه نویس باید خودشان توافق کنند. حدود 80 تا 120 کاراکتر نرمال است.
تورفتگی کدها (Indent):
دو نوع تورفتگی در اسکریپت می توان تعریف کرد:
- افقی (Horizontal); شامل 2 یا 4 فاصله (space): تو رفتگی افقی می تواند بوسیله زدن 2 یا 4 فاصله رخ دهد یا توسط دکمه Tab صفحه کلید. البته استفاده از space مرسوم تر است زیرا قابلیت تغییر و انعطاف بیشتری نسبت به tab دارد. بعنوان مثال:
show(parameters, aligned, // 5 spaces padding at the left one, after, another ) { // ... }
- عمودی (Vertical); شامل خط های خالی که باعث جدا شدن دستورات هر بلاک می شود:
حتی یک تابع هم می تواند به چند بلاک مجزا بخش بندی شود. اینکار توسط فاصله های عمودی صورت می گیرد. در مثال زیر، دستوری که یک متغیر را تعریف می کند، و دستوری که شامل حلقه for است و دستور آخر یعنی return هر کدام با فاصله (یک Enter و کامنت) از هم تعریف شده اند.
function pow(x, n) { let result = 1; // <-- for (let i = 0; i < n; i++) { result *= x; } // <-- return result; }
Semicolons (;)
پس از هر عبارت باید از علامت ; در جاوا اسکریپت استفاده شود. با اینکه در برخی از زبان های برنامه نویسی می توان در انتهای دستورات از سمیکالن استفاده نکرد، در جاوا اسکریپت مواردی وجود دارد که عدم تعریف علامت ; در آخر عبارات ممکن است باعث بروز خطا در اجرای جاوا اسکریپتی شود (مواقعی که line break بعنوان یک semicolon تفسیر نمی شود).
سطوح تودرتو نویسی (Nesting Levels):
سعی شود از تو در تو نویسی (Nested) در سطوح عمیق خودداری کنید. بعنوان مثال داریم:
for (let i = 0; i < 10; i++) { if (cond) { ... // <- one more nesting level } }
در مثال بالا می توان توسط دستور continue سطوح تودرتو نویسی را کاهش داد:
for (let i = 0; i < 10; i++) { if (!cond) continue; ... // <- no extra nesting level }
همچنین می توان در دستورات شرطی if/else نیز این موارد را رعایت کرد. بعنوان مثال دو قطعه کد زیر یک کار را انجام می دهند:
کد 1:
function pow(x, n) { if (n < 0) { alert("Negative 'n' not supported"); } else { let result = 1; for (let i = 0; i < n; i++) { result *= x; } return result; } }
کد 2:
function pow(x, n) { if (n < 0) { alert("Negative 'n' not supported"); return; } let result = 1; for (let i = 0; i < n; i++) { result *= x; } return result; }
مشخص است که کد 2 خواناتر است. زیرا به دستور else نیازی نیست و قابل حذف است.
محل تعریف تابع (function-placement):
اگر توابعی دارید که بصورت helper هستند یعنی در برنامه فراخوانی خواهند شد می توان آن ها را به 3 طریق زیر تعریف کرد:
- توابع در بالا تعریف شوند و فراخوانی آنها در پایین:
// function declarations function createElement() { ... } function setHandler(elem) { ... } function walkAround() { ... } // the code which uses them let elem = createElement(); setHandler(elem); walkAround();
- ابتدا فراخوانی توابع تعریف شود سپس بدنه توابع صدا زده شده:
// the code which uses the functions let elem = createElement(); setHandler(elem); walkAround(); // --- helper functions --- function createElement() { ... } function setHandler(elem) { ... } function walkAround() { ... }
- ترکیب دو روش بالا: ابتدا هر فانکشن تعریف شود سپس call شود.
Automated Linters:
لینترها ابزاری هستند که می توانند بطور اتوماتیک سبک کدنویسی شما را بررسی کرده و در جهت بهبود آن پیشنهاداتی ارائه دهند. Linter ها همچنین امکان شناسایی باگ را در برخی موارد دارند. مانند اشتباه املایی در متغیرها یا نام توابع و…
به همین دلایل استفاده از یکی از ابزارهای linter پیشنهاد می شود حتی اگر از سبک کدنویسی (coding-style) خاصی پیروی نمی کنید.
در بخش زیر تعدادی از معروف ترین ابزارهای linter نام برده شده است:
- JSLint: یکی از اولین لینترهای جاوا اسکریپتی
- JSHint: دارای امکانات و تنظیمات بیشتری نسبت به JSLint
- ESLint: جدیدترین ابزار Lint در جاوا اسکریپت
تمام لینترهای فوق می توانند کار ما را راه بیاندازند اما ما در این آموزش از ESLint استفاده می کنیم.
اغلب لینترها در ادیتورهای محبوب برنامه نویسان (مانند Visual Studio Code و Web Storm و…) پشتیبانی می شوند. فقط کافیست آن را در editor موردنظر نصب کرده و استفاده کنید.
نحوه استفاده از ابزار ESLint:
بعنوان مثال برای کار با ابزار ESLint باید مراحل زیر را انجام دهید:
- نصب Node.js
- نصب ESLint توسط node package manager (npm) و اجرای دستور npm install -g eslint
- ایجاد یک فایل بنام .eslintrc در روت پروژه جاوا اسکریپت
- نصب و فعال سازی پلاگین مربوط به ESLint در ادیتور
نمونه ای از سورس کد فایل eslintrc:
{ "extends": "eslint:recommended", "env": { "browser": true, "node": true, "es6": true }, "rules": { "no-console": 0, "indent": ["warning", 2] } }
با مراجعه به وب سایت مرجع ESLint می توانید نحوه کار با آن را یاد بگیرید.
کامنت گذاری (Comments):
همانطور که در بخش های قبل ذکر کردیم، کامنت در جاوااسکریپت می تواند به دو شکل یک خطی توسط // و چندخطی توسط /* … */ انجام شود. معمولا برای توضیح دلایل و چگونگی تعریف قطعه کدها از کامنت استفاده می شود.
در نگاه اول شاید بنظر برسد مبحث کامنت گذاری ساده و واضح است اما در واقع برخی از برنامه نویسان تازه کار به اشتباه از آن استفاده می کنند.
» کامنت گذاری به روش نادرست:
برنامه نویسان تازه کار ممکن است یک قطعه کد پیچیده را بطور کامل در کامنت شرح دهند:
// This code will do this thing (...) and that thing (...) // ...and who knows what else... very; complex; code;
اما یک قطعه کد خوب و بهینه باید بقدری واضح باشد که نیاز به اینهمه کامنت نوشتن و شرح و تفصیل نداشته باشد. کامنت باید مختصر و مفید باشد.
یک جمله زیبا هست که میگه:
” اگر یک قطعه کد بقدری پیچیده است که نیاز به نوشتن کامنت های طولانی و چند خطی دارد، بهتر است آن قطعه کد مجددا از ابتدا نوشته شود!”
بنابراین سعی کنید توابعی تعریف کنید که نحوه کدنویسی آن ها واضح و تمیز باشد. بعنوان مثال در تابع زیر نیاز است کامنت نوشته شود:
function showPrimes(n) { nextPrime: for (let i = 2; i < n; i++) { // check if i is a prime number for (let j = 2; j < i; j++) { if (i % j == 0) continue nextPrime; } alert(i); } }
اما اگر همین تابع را به شکل زیر تعریف کنیم (isPrime) دیگر نیازی به تعریف کامنت نیست و خود تابع مشخص است چکار می کند:
function showPrimes(n) { for (let i = 2; i < n; i++) { if (!isPrime(i)) continue; alert(i); } } function isPrime(n) { for (let i = 2; i < n; i++) { if (n % i == 0) return false; } return true; }
به اینگونه توابع (که مشخص است چگونه کار می کنند و نیازی به توضیح اضافی ندارند) self-descriptive می گویند.
نکته دیگر اینکه اگر کد جاوا اسکریپت شما طولانی است بهتر است آن را به چند تابع تقسیم بندی کنید. مثال زیر:
// here we add whiskey for(let i = 0; i < 10; i++) { let drop = getWhiskey(); smell(drop); add(drop, glass); } // here we add juice for(let t = 0; t < 3; t++) { let tomato = getTomato(); examine(tomato); let juice = press(tomato); add(juice, glass); } // ...
سپس در کد زیر دو تابع برای هر یک از حلقه ها تعریف کردیم:
addWhiskey(glass); addJuice(glass); function addWhiskey(container) { for(let i = 0; i < 10; i++) { let drop = getWhiskey(); //... } } function addJuice(container) { for(let t = 0; t < 3; t++) { let tomato = getTomato(); //... } }
خود توابع گویای کار هستند و نیازی به کامنت گذاری نمی باشد.
توجه کنید که بطور کلی برای توابع و قطعه کدهای پیشرفته تر نیاز به کامنت نوشتن خواهیم داشت اما در حد ممکن باشد کدهایمان شفاف و تمیز باشند که کمتر نیاز به توضیح داشته باشند.
» کامنت گذاری به روش صحیح:
بنابراین تا الان متوجه شدیم که کامنت گذاری طولانی معمولا درست نیست. اما چگونه می توان برای اسکریپت های خود کامنت خوب تعریف کنیم؟
برای بیان معماری کد تعریف شده در سطح بالا، چگونگی تعامل آن با سایر توابع و… در این زمینه مطالعه مستندات UML می تواند به شما کمک کند.
داکیومنت کردن پارامترهای تابع و مقدار خروجی آن:
یک استاندارد مشخصی برای داکیومنت کردن توابع جاوا اسکریپتی وجود دارد بنام JSDoc که شامل کاربرد و نحوه استفاده از آن، توضیح پارامترهای ورودی و مقدار بازگردانده شده تابع می شود.
بعنوان نمونه:
/** * Returns x raised to the n-th power. * * @param {number} x The number to raise. * @param {number} n The power, must be a natural number. * @return {number} x raised to the n-th power. */ function pow(x, n) { ... }
کامنت هایی به شکل فوق باعث می شود نحوه کارکرد تابع را بهمراه پارامترهای ورودی و خروجی آن را متوجه شویم. یدون اینکه نیاز باشد کدهای تابع را بررسی کنیم. برخی از ادیتورها مانند Webstorm از این ساختار کامنت گذاری پشتیبانی می کنند و قابلیت امکان autocomplete دارند.
در فصل هفتم، قصد داریم تمام مباحث مربوط به آبجکت یا شیء را در جاوا اسکریپت آموزش دهیم.
دیدگاهتان را بنویسید