برای هر کسی که با این مسئله آشنا نیست، بگویم که Google یک راهنمای استایل برای نوشتن JavaScript را منتشر میکند و این راهنما بهترین شیوههای استایل را برای نوشتن یک کد تمیز و قابل درک به نمایش میگذارد.
این راهنماها، قوانین سفت و سختی برای نوشتن یک کد JavaScript معتبر نیستند؛ بلکه فقط برای نگه داشتن استایلهای باثبات و جذاب در فایلهای منبع شما میباشند. این مسئله به خصوص برای JavaScript، یک زبان منعطف که تنوع عظیمی از استایلها را ممکن میسازد، جالب است.
Google و Airbnd دو مورد از معروفترین استایلهای موجود را دارند. اگر شما زمان زیادی را صرف نوشتن JS مینمایید، به شدت پیشنهاد میکنم که به هر دوی آنها نگاهی داشته باشید.
در ادامه، ۱۳ مورد از قوانین راهنمای استایل Google را مشاهده مینمایید که به نظر من جالبترین و مرتبطترین موارد هستند.
این موارد با هر چیزی از مشکلات داغ و مورد بحث (tab در مقابل space، و مشکل بحث برانگیز سمی کالنها) گرفته تا برخی مشخصههای مبهم دیگر که مرا شگفتزده کردند، سر و کله میزنند. این ۱۳ مورد به طور قطعی نحوه JavaScript نوشتن من را تغییر خواهند داد.
برای هر قانون، من یک خلاصه از مشخصه مربوطه به همراه یک نقل قول پشتیبان از راهنمای استایل دارم که قانون مورد نظر را به همراه جزئیات توضیح میدهد. در جایی که ممکن باشد، همچنین یک مثال از استایل مورد نظر در عمل را فراهم کرده، و آن را در مقابل یک کد که از آن قانون پیروی نمیکند قرار خواهم داد.
از space استفاده کنید، نه tab
«جدا از توالی از بین برنده خط، فاصله افقی ASCII (0 x 20) تنها کاراکتر فضای خالی است که در هر جایی از یک فایل منبع نمایان میشود. این نشان میدهد که کاراکترهای tab برای فرورفتگی استفاده نمیشوند.»
این راهنما سپس میگوید که شما باید از دو (و نه چهار) space برای فرورفتگی استفاده کنید.
// بد
function foo() {
∙∙∙∙let name;
}
// بد
function bar() {
∙let name;
}
// خوب
function baz() {
∙∙let name;
}
سمیکالنها مورد نیاز هستند
«هر بیانیهای باید با استفاده از یک سمی کالن قطع شود. تکیه کردن به وارد کردن خودکار سمی کالن، ممنوع است.»
با این که درک نمیکنم چرا همه با این ایده مخالفند، استفاده مداوم از سمی کالنها در JS در حال تبدیل شدن به نسخه جدید از بحث «spaceها در مقابل tabها» میباشد. Google در اینجا به دفاع از سمی کالن میآید.
// بد
let luke = {}
let leia = {}
[luke, leia].forEach(jedi => jedi.father = 'vader')
// خوب
let luke = {};
let leia = {};
[luke, leia].forEach((jedi) => {
jedi.father = 'vader';
});
(هنوز) از ماژولهای ES6 استفاده نکنید
«هنوز از ماژولهای ES6 (کلیدواژههای export و import) استفاده نکنید؛ زیرا معنای آنها هنوز نهایی نشده است. دقت کنید که این سیاست پس از این که معنای آنها کاملا استانداد شده باشد، باز هم بررسی خواهد شد.»
// هنوز چنین کاری نکنید:
//------ lib.js ------
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
alignment افقی پیشنهاد نمیشود (اما ممنوع نیست)
«این شیوه مجاز است، اما عموما توسط استایل Google پیشنهاد نمیشود. این شیوه حتی برای نگهداری alignment افقی در جاهایی که از پیش استفاده شده بود هم مورد نیاز نیست.»
تراز افقی، شیوه اضافه کردن یک عدد متغیر از فاصلههای اضافی در کد شما است، تا مطمئن شوید که نشانهها دقیقا زیر نشانههای دیگر بر روی خط قبلی ظاهر میشود.
// بد
{
tiny: 42,
longer: 435,
};
// خوب
{
tiny: 42,
longer: 435,
};
دیگر از var استفاده نکنید
«همه متغیرهای محلی را یا با استفاده از const و یا let تعریف کنید. به طور پیشفرض از const استفاده کنید؛ مگر این که یک متغیر باید مجددا اختصاصدهی شود. از کلیدواژه var نباید استفاده کرد.»
من همچنان میبینم که افراد در نمونه کدهای بر روی StackOverflow یا هر جای دیگری از var استفاده میکنند. نمیدانم افرادی وجود دارند که از آن استفاده خوبی میبرند، یا این فقط یک عادت قدیمی است.
// بد
var example = 42;
// خوب
let example = 42;
توابع پیکانی بهترند
«توابع پیکانی یک سینتکس مختصر را فراهم میکنند. توابع پیکانی را به کلیدواژه function ترجیح دهید؛ به خصوص برای توابع تو در تو.»
بگذارید با شما روراست باشم. من فکر میکردم توابع پیکانی فقط به این دلیل خوبند که مختصرتر بوده و ظاهر بهتری دارند. به نظر میرسد که این توابع همچنین به تحقق یافتن یک هدف بهتر هم کمک میکنند.
// بد
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
// خوب
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
به جای الحاق، از رشتههای قالب استفاده کنید
«از رشتههای قالب (که با استفاده از ‘ تعریف میشوند) به جای الحاقهای رشته پیچیده استفاده کنید. به خصوص اگر چندین رشته دخیل هستند. رشتههای قالب شاید چندین خط طول داشته باشند.»
// بد
function sayHi(name) {
return 'How are you, ' + name + '?';
}
// بد
function sayHi(name) {
return ['How are you, ', name, '?'].join();
}
// بد
function sayHi(name) {
return `How are you, ${ name }?`;
}
// خوب
function sayHi(name) {
return `How are you, ${name}?`;
}
برای رشتههای طولانی از تمدید خط استفاده نکنید
«از تمدید خطها (تمام کردن یک رشته داخل یک رشته، با استفاده از یک بکاسلش) در رشتههای قالب یا معمولی استفاده نکنید. با این که ES5 این کار را ممکن میسازد، اما اگر هر نوع فضای خالی پیشین قبل از اسلش بیاید، میتواند به خطاهای پیچیدهای ختم شود و برای خوانندگان وضوح کمتری دارد.»
گرچه جالب این است که Google و Airbnd بر روی این قانون با هم اختلاف دارند.
با این که Google متمرکز کردن رشتههای طولانی (به مانند زیر) را پیشنهاد میکند، اما راهنمای استایل Airbnd پیشنهاد میکند که هیچ کاری انجام ندهید، و بگذارید رشتههای طولانی تا جایی که میخواهند طولانی شوند.
// بد (شرمنده، این کد در موبایل به خوبی نمایش داده نمیشود)
const longString = 'This is a very long string that \
far exceeds the 80 column limit. It unfortunately \
contains long stretches of spaces due to how the \
continued lines are indented.';
// خوب
const longString = 'This is a very long string that ' +
'far exceeds the 80 column limit. It does not contain ' +
'long stretches of spaces since the concatenated ' +
'strings are cleaner.';
For… of نوع ترجیح داده شده حلقه for است.
«با ES6 زبان JavaScript سه نوع مختلف از حلقهها را دارد. از تمام آنها میتوان استفاده کرد، اما در صورت ممکن باید for-of را ترجیح داد.»
من همیشه تحت تاثیر این بودم که حلقههای for… in برای آبجکتها بهتر بوده، و for… of هم برای آرایهها بهتر بود.
با این که در اینجا مشخصه Google با این ایده تناقض ندارد، اما همچنان جالب است بدانید که آنها به خصوص این حلقه را ترجیح میدهند.
از eval() استفاده نکنید
«از eval یا سازنده تابع استفاده نکنید. این ویژگیها احتمال خطرناک بودن را داشته و به سادگی در محیطهای CSP کار نمیکنند.»
صفحه MDN برای eval() یک بخش به نام «Don’t use eval!» دارد.»
// بد
let obj = { a: 20, b: 30 };
let propName = getPropName(); // returns "a" or "b"
eval( 'var result = obj.' + propName );
// خوب
let obj = { a: 20, b: 30 };
let propName = getPropName(); // returns "a" or "b"
let result = obj[ propName ]; // obj[ "a" ] is the same as obj.a
Constantها باید تماما با حروف بزرگ نوشته شده، و با استفاده از آندرلاین جدا شوند
«نامهای constant تماما با حروف بزرگ و جدا شده با استفاده از آندرلااین نوشته میشوند.»
اگر شما کاملا مطمئنید که یک متغیر نباید تغییر کند، میتوانید با بزرگ کردن اولین حرف constant مورد نظر آن را نشان دهید.
یک استثنای قابل توجه برای این قانون، وقتی است که constant مورد نظر در محدوده تابع است. در این صورت، به صورت camelCase نوشته خواهد شد.
// بد
const number = 5;
// خوب
const NUMBER = 5;
یک متغیر به ازای هر تعریف
«هر تعریف متغیر محلی، فقط یک متغیر را تعریف میکند. از تعریفاتی مانند let a = 1, b = 2; استفاده نکنید.»
// بد
let a = 1, b = 2, c = 3;
// خوب
let a = 1;
let b = 2;
let c = 3;
از سینگل کوتیشن استفاده کنید، نه دابل کوتیشن
«رشتههای معمولی با یک سینگل کوتیشن (‘) نشان داده میشوند، نه دابل کوتیشن (“).»
// بد
let directive = "No identification of self or mission."
// بد
let saying = 'Say it ain\u0027t so.';
// خوب
let directive = 'No identification of self or mission.';
// خوب
let saying = `Say it ain't so`;
یک نکته آخر
همانطور که در ابتدا گفتم، این موارد دستور نیستند. Google فقط یکی از چند غول فناوری است و این موارد فقط پیشنهادات هستند.
با توجه به این جمله، جالب است که به پیشنهادات استایل منتشر شده توسط شرکتهایی مانند Google، شرکتی که تعداد زیادی افراد باهوش را استخدام میکند و این افراد هم مقدار زیادی زمان را صرف نوشتن یک کد عالی مینمایند، نگاهی داشته باشید.
شما اگر بخواهید میتوانید از این قوانین پیروی کنید، و البته که بسیاری از افراد با آنها مخالفت میکنند. شما میتوانید هر کدام از این موارد را به دلخواه خود خط بزنید.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید