23 تکنیک جاوااسکریپت برای مبتدیان

آفلاین
user-avatar
عرفان حشمتی
23 مهر 1400, خواندن در 13 دقیقه

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

در این مقاله قصد داریم 23 تکنیک جاوااسکریپت را مورد بررسی قرار دهیم که هر کسی باید آنها را رعایت کند. از بهینه سازی و سهولت خواندن کد گرفته تا اجتناب از مقادیر گلوبال و برخی نکات عملکردی.

1. استفاده از === به جای ==

جاوااسکریپت از دو نوع عملگر برابری مختلف استفاده می‌کند: === و ==! عملگرهای strict، == و =! هم عملگرهای non-strict هستند. بهترین کار این است که برای مقایسه همیشه از نوع strict استفاده شود.

توجه: اگر دو عملوند دارای نوع و مقدار یکسانی باشند، === مقدار true و ==! مقدار false تولید می‌کند.

با این حال موقع استفاده از == و =! هنگام کار با انواع داده مختلف به مشکل برمی‌خورید. وقتی مقادیری که مقایسه می‌کنید انواع داده مختلفی داشته باشد، اپراتورهای non-strict سعی می‌کنند مقادیر خود را تحمیل کنند و ممکن است نتایج غیر منتظره‌ای به دست آید.

2. از ()eval استفاده نکنید

برای کسانی که ناآشنا هستند، تابع ()eval دسترسی به کامپایلر جاوااسکریپت را به ما می‌دهد. در اصل می‌توانیم یک رشته را با ارسال آن به عنوان پارامتر ()eval اجرا کنیم.

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

3. از مختصرنویسی استفاده نکنید

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

if(someVariableExists)

   x = false

همچنین این را در نظر بگیرید:

if(someVariableExists)

   x = false

     anotherFunctionCall();

شاید فکر کنید کد بالا معادل کد زیر است:

if(someVariableExists) {

   x = false;

   anotherFunctionCall();

}

اما سخت در اشتباه هستید! در واقع به این معنی است:

if(someVariableExists) {
   x = false;
}
anotherFunctionCall();

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

if(2 + 2 === 4) return 'nicely done';

همیشه آینده را در نظر بگیرید. اگر بعدا نیاز باشد دستورات بیشتری به if اضافه کنید چه؟ برای انجام این کار باید بلوک کد را بازنویسی کنید. پس بدین منظور با احتیاط عمل نمایید.

4. بهره گیری از JSLint

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

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

قبل از تایید اسکریپت، آن را از طریق JSLint اجرا کنید تا مطمئن شوید که هیچ اشتباهی مرتکب نشده‌اید.

5. اسکریپت‌ها را در پایین داکیومنت خود قرار دهید

این نکته بارها در مقالات و ویدئوهای قبلی توصیه شده است.

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

اگر فایلهای جاوااسکریپتی دارید که هدف آنها تنها افزودن قابلیتهاست، پس بروید و آن فایلها را در قسمت پایین، درست قبل از بسته شدن تگ اصلی قرار دهید.

<p>And now you know my favorite kinds of corn. </p>
<script type="text/javascript" src="path/to/file.js"></script>
<script type="text/javascript" src="path/to/anotherFile.js"></script>
</body>
</html>

 6. متغیرها را خارج از حلقه for تعریف کنید

هنگام اجرای دستورات for طولانی، اجازه ندهید کامپایلر بیش از حد کار کند. برای مثال:

for(var i = 0; i < someArray.length; i++) {
   var container = document.getElementById('container');
   container.innerHtml += 'my number: ' + i;
   console.log(i);

}

توجه کنید که چگونه باید طول آرایه را برای هر تکرار تعیین کنیم و چگونه از DOM عبور می‌کنیم تا هر بار عنصر "container" را پیدا کنیم. این کد بسیار ناکارآمد است.

پس بهتر است آن را به صورت زیر بهبنه کنیم:

var container = document.getElementById('container');
for(var i = 0, len = someArray.length; i < len;  i++) {
   container.innerHtml += 'my number: ' + i;
   console.log(i);
}

7. سریعترین راه برای ساختن String

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

var arr = ['item 1', 'item 2', 'item 3', ...];
var list = '<ul><li>' + arr.join('</li><li>') + '</li></ul>';

نمی‌خواهم شما را با بررسی معیارها خسته کنم، فقط باید این را باور کنید (خودتان آزمایش کنید).

استفاده از روش‌های سنتی مانند ()join صرف نظر از آنچه در پشت لایه انتزاعی می‌گذرد، معمولا بسیار سریعتر از هر جایگزین دیگری است.

8. استفاده از Template Literalها

رشته‌هایی که با سینگل یا دبل کوتیشن‌ها ایجاد می‌کنیم دارای محدودیت‌های زیادی است. ممکن است بخواهید برخی از رشته‌های خود را با template literalها جایگزین کنید تا کار با آنها آسان‌تر شود. اینها با استفاده از کاراکتر backtick (`) ایجاد می‌شوند و مزایای زیادی را به همراه دارند. می‌توانید عبارات را داخل آنها قرار دهید و رشته‌های چند خطی ایجاد کنید.

let person = 'Monty';
let fruits = 'apples';
let activity = 'playing games';
let day = 'Monday';

var sentence = person + ' will be eating ' + fruits + ' and ' + activity + ' on ' + day + '.';
console.log(sentence);

// Output: Monty will be eating apples and playing games on Monday.
var sentence = `${person} will be eating ${fruits} and ${activity} on ${day}.`;
console.log(sentence);
// Output: Monty will be eating apples and playing games on Monday.

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

9. کاهش تعداد مقادیر گلوبال

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

var name = 'Jeffrey';
var lastName = 'Way';
function doSomething() {...}
console.log(name); // Jeffrey -- or window.name

پس بهتر است کد بالا را به این شکل بهینه کنیم:

var DudeNameSpace = {
   name : 'Jeffrey',
   lastName : 'Way',
   doSomething : function() {...}
}

console.log(DudeNameSpace.name); // Jeffrey

توجه کنید که چگونه مقادیر خود را به شیء DudeNameSpace محدود کرده‌ایم.

10. استفاده از let و const را در نظر بگیرید

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

var person_name = "Adam";

let name_length = person_name.length;

const fav_website = "code.tutsplus.com";




if(person_name.length < 5) {

    var person_name = "Andrew";

    let name_length = person_name.length;

     

    // Throws an error if commented out!

    // fav_website = "webdesign.tutsplus.com";




    console.log(`${person_name} has ${name_length} characters.`);

    // Output: Andrew has 6 characters.

}




console.log(`${person_name} has ${name_length} characters.`);

// Output: Andrew has 4 characters.

در مثال بالا پس از اینکه مقدار متغیر person_name را در داخل بلوک تغییر دادیم، در خارج از بلوک if نیز به روز شد. از طرف دیگر name_length به صورت بلوکی مورد استفاده قرار گرفته، بنابراین مقدار اصلی خود را در خارج از بلوک حفظ می‌کند.

11. کامنت گذاری را فراموش نکنید

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

// Cycle through array and echo out each name.
for(var i = 0, len = array.length; i < len; i++) {
   console.log(array[i]);
}

12. از توسعه تدریجی استقبال کنید

همیشه فرض را بر این بگذارید که جاوااسکریپت غیرفعال است. اکثر افراد جاوااسکریپت را فعال نگه می‌دارند، بنابراین هیچ جای نگرانی وجود ندارد. هرچند یک اشتباه بزرگ خواهد بود.

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

13. رشته‌ها را به setInterval یا setTimeOut منتقل نکنید

کد زیر را در نظر بگیرید:

setInterval(
"document.getElementById('container').innerHTML += 'My new number: ' + i", 3000
);

این کد نه تنها ناکارآمد نیست، بلکه عملکردی مشابه با متد "eval" دارد. هرگز رشته‌ای را به setInterval و setTimeOut منتقل نکنید. در عوض نام تابع را ارسال کنید.

setInterval(someFunction, 3000); 

14. استفاده از {} به جای new Object()

روشهای مختلفی برای ایجاد اشیاء در جاوااسکریپت وجود دارد. روش سنتی‌تر می‌تواند استفاده از کانستراکتور new باشد، مانند موارد زیر:

var o = new Object();
o.name = 'Jeffrey';
o.lastName = 'Way';
o.someFunction = function() {
   console.log(this.name);
}

با این حال یک روش نامناسب در نظر گرفته می‌شود. این در واقع مضر نیست، اما کمی طولانی و غیرمعمول است. در عوض توصیه می‌کنم از Object Literal کمک بگیرید.

بهتر است کد بالا را به این شکل بهینه کنیم:

var o = {
   name: 'Jeffrey',
   lastName = 'Way',
   someFunction : function() {
      console.log(this.name);
   }
};

توجه داشته باشید که اگر به سادگی می‌خواهید یک شیء تهی ایجاد کنید، {} این کار را انجام می‌دهد.

var o = {};

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

15. استفاده از [ ] به جای new Array()

همین امر در مورد ایجاد یک آرایه جدید نیز صدق می‌کند.

با اینکه کد زیر درست است:

var a = new Array();
a[0] = "Joe";
a[1] = 'Plumber';

اما بهتر است اینگونه نوشته شود:

var a = ['Joe','Plumber'];

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

16. استفاده از عملگر Spread

آیا تا به حال در موقعیتی قرار گرفته‌اید که بخواهید همه آیتم‌های یک آرایه را به عنوان عناصر جداگانه به تابع دیگری منتقل کنید یا بخواهید همه مقادیر را از یک آرایه به آرایه دیگر وارد کنید؟ عملگرspread  (...) به ما امکان می‌دهد دقیقا همین کار را انجام دهیم. به عنوان مثال:

let people = ["adam", "monty", "andrew"]
let more_people = ["james", "jack", ...people, "sajal"]

console.log(more_people)
// Output: Array(6) [ "james", "jack", "adam", "monty", "andrew", "sajal" ]

17. هنگام نوشتن عبارات for … in مراقب باشید

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

for(key in object) {
   if(object.hasOwnProperty(key) {
      ...then do something...
   }
}

18. بیشتر مطالعه کنید

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

  • Object-Oriented JavaScript
  • JavaScript: The Good Parts
  • Learning JavaScript

سعی کنید آنها را چندین بار بخوانید. من هنوز هم این کار را انجام می‌دهم.

19. اجرای توابع به صورت خودکار

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

(function doSomething() {
   return {
      name: 'jeff',
      lastName: 'way'
   };
})();

20. جاوااسکریپت خام همیشه سریعتر از کتابخانه است

کتابخانه‌های جاوااسکریپت مانند jQuery و lodash می‌توانند زمان زیادی را هنگام برنامه‌نویسی صرفه‌جویی کنند، مخصوصا با استفاده از عملیات AJAX. با این اوصاف همیشه به خاطر داشته باشید که یک کتابخانه هرگز نمی‌تواند به سرعت جاوااسکریپت خام (با فرض کدنویسی درست) باشد.

متد each() جی کوئری برای حلقه زدن بسیار عالی است، اما استفاده از دستور سنتی for همیشه یک مقدار سریعتر خواهد بود.

21. به سرعت مقادیر متغیر را با Destructuring تعیین کنید

قبلا در مورد عملگر spread در جاوااسکریپت صحبت کردیم. destructuring هم تا حدودی شبیه به آن است که مقادیر ذخیره شده درون آرایه‌ها را نیز باز می‌کند. تفاوت در این است که ما می‌توانیم این مقادیر باز شده را به متغیرهای unique اختصاص دهیم.

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

let [person, fruit, , day] = ['Monty', 'apple', 'reading', 'tomorrow'];
var sentence = `${person} will eat an ${fruit} ${day}.`;

console.log(sentence);
// Output: Monty will eat an apple tomorrow.

آیا متوجه شدید که چگونه از انتساب عنصر سوم آرایه به متغیر با عبور ندادن نام متغیر صرف نظر کردیم؟ این به ما اجازه می‌دهد تا از تعیین متغیرها برای مقادیری که نیازی به آن نداریم، اجتناب کنیم.

22. Iteratorها و حلقه‌های for … of

Iteratorها در جاوااسکریپت اشیایی هستند که متد ()next را پیاده سازی می‌کنند (به منظور بازگشت شیئی که مقدار بعدی را در یک دنباله به صورت true یا false ذخیره می‌کند، بسته به اینکه مقدار دیگری باقی مانده است یا نه). این بدان معناست که اگر پروتکل iterator را اجرا کنید، می توانید اشیاء iterator خود را ایجاد نمایید.

جاوااسکریپت همچنین دارای iteratorهای داخلی مانند String ،Array ، Map و ... است که می‌توانید با استفاده از حلقه‌های for … of روی آنها عملیات تکرار را انجام دهید. این در مقایسه با حلقه‌های معمولی مختصرتر و کمتر مستعد خطا است.

let people = ["Andrew", "Adam", "James", "Jack"];
let people_count = people.length;

for(let i = 0; i < people_count; i++) {
    console.log(people[i]);
}

/*
Andrew
Adam
James
Jack
*/

for(person of people) {
    console.log(person);
}

/*
Andrew
Adam
James
Jack
*/

با کمک حلقه for … of دیگر مجبور نیستیم طول کل آرایه یا اندیس فعلی را نگهداری کنیم. این می‌تواند پیچیدگی کد را هنگام ایجاد حلقه‌های تو در تو کاهش دهد.

23. Async و Await

میتوانید از کلمه کلیدی async برای ایجاد توابع ناهمزمان استفاده کنید که همیشه promise را به طور صریح یا ضمنی برمی‌گرداند. توابع ناهمزمانی که ایجاد می‌کنید می‌توانند با توقف اجرا تا زمان حل promiseهای بازگشتی، از کلمه کلیدی await استفاده کنند. کد خارج از تابع async به طور معمول اجرا می‌شود.

async function delayed_hello() {
    console.log("Hello Adam!");
    let promise = new Promise((resolve) => {
        setTimeout(() => resolve("Hello Andrew!"), 2000)
    });

    let result = await promise;
    console.log(result);
}
console.log("Hello Monty!");
delayed_hello();
console.log("Hello Sajal!");
/*
Hello Monty!
Hello Adam!
Hello Sajal!
Hello Andrew!
*/

در مثال بالا "Hello Andrew" پس از دو ثانیه ثبت می‌شود، در حالی که برای بقیه helloهای دیگر بلافاصله این اتفاق می‌افتد. با فراخوانی تابع delayed_hello() بلافاصله “Hello Adam” ثبت شده، اما منتظر می‌ماند تا promise به منظور ثبت “Hello Andrew” حل شود.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

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

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

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو