أفضل الممارسات للتكرار في JavaScript
توضح هذه المقالة أفضل الممارسات للتكرار في JavaScript۔
YouTube Video
أفضل الممارسات للتكرار في JavaScript
من الشائع استخدام حلقات for
للتكرار في JavaScript۔ هنا، سنقدم شرحًا تفصيليًا لأفضل الممارسات لاستخدام حلقات for
لكتابة كود فعال وقابل للقراءة۔
اختر بنية التكرار المناسبة
يوفر JavaScript العديد من تكوينات التكرار، لكل منها غرض مختلف۔
1// Example of a for loop
2for (let i = 0; i < 5; i++) {
3 console.log(i);
4}
5
6// Example of a for...of loop
7const array = [10, 20, 30];
8for (const value of array) {
9 console.log(value);
10}
11
12// Example of a for...in loop
13const obj = { a: 1, b: 2, c: 3 };
14for (const key in obj) {
15 console.log(`${key}: ${obj[key]}`);
16}
17
18// Example of a while loop
19let count = 0;
20while (count < 5) {
21 console.log(count);
22 count++;
23}
- عبارة
for
مناسبة عندما يكون عدد التكرارات محدداً مسبقاً.۔ - عبارة
for...of
مناسبة لمعالجة المصفوفات والكائنات القابلة للتكرار بشكل مختصر.۔ - تُستخدم عبارة
for...in
للتكرار عبر خصائص الكائن.۔ ومع ذلك، فهي غير مناسبة للمصفوفات۔ - تُستخدم عبارات
while
وdo...while
للتحكم في الدورات بناءً على الشروط.۔
استخدام طريقة forEach
وعبارة for...of
.
عند تكرار المرور عبر مصفوفة، من الشائع استخدام عبارة for
للوصول إلى الفهرس، ولكن قد تكون طريقة forEach
أو عبارة for...of
أكثر وضوحًا.۔
1// Using a standard for loop
2const array = ["apple", "banana", "cherry"];
3for (let i = 0; i < array.length; i++) {
4 console.log(array[i]);
5}
6
7// Using forEach
8array.forEach(item => console.log(item));
9
10// Using for...of
11for (const item of array) {
12 console.log(item);
13}
- تسمح عبارة
for
بالتحكم المباشر بالفهرس أثناء التكرار.۔ - تستخدم طريقة
forEach
دالة رد استدعاء لمعالجة كل عنصر بشكل مختصر.۔ - عبارة
for...of
تتمتع بوضوح عالٍ وتتيح الوصول المباشر إلى كل عنصر في المصفوفة.۔
قم بتحسين شروط التكرار
نظرًا لأن شرط التكرار يتم تقييمه بشكل متكرر، فإن تجنب العمليات الحسابية غير الضرورية يمكن أن يُحسن الأداء۔
1const names = ["Alice", "Bob", "Charlie"];
2const scores = [85, 92, 78];
3
4// Inefficient example
5for (let i = 0; i < Math.min(names.length, scores.length); i++) {
6 console.log(`${names[i]} scored ${scores[i]}`);
7}
8
9// Efficient example
10for (let i = 0, len = Math.min(names.length, scores.length); i < len; i++) {
11 console.log(`${names[i]} scored ${scores[i]}`);
12}
- كما هو موضح في هذا المثال، فإن تخزين نتيجة الحساب في متغير مسبقاً يتيح تنفيذ الحلقات بشكل أكثر كفاءة۔
1const scores = [85, 92, 78];
2let sum = 0;
3let sum2 = 0;
4
5// Inefficient example
6for (let i = 0; i < scores.length; i++) {
7 sum += scores[i];
8}
9console.log(`Total score : ${sum}`);
10
11// Efficient example
12for (let i = scores.length - 1; i >= 0; i--) {
13 sum2 += scores[i];
14}
15console.log(`Total score : ${sum2}`);
- كما هو موضح في هذا المثال، فإن عكس الشرط يمكن أن يكون أحيانًا أكثر كفاءة۔
تحسين معالجة الحلقات
نظرًا لأن معالجة الحلقات تُنفذ بشكل متكرر، فإن تجنب الحسابات غير الضرورية يمكن أن يحسن الأداء۔
1const array = ["apple", "banana", "cherry"];
2
3// Inefficient example
4for (let i = 0; i < 100; i++) {
5 const element = document.querySelector("#myElement");
6 element.textContent = `Count: ${i}`;
7}
8
9// Efficient example
10const element = document.querySelector("#myElement");
11for (let i = 0; i < 100; i++) {
12 element.textContent = `Count: ${i}`;
13}
- في هذا المثال، من خلال نقل طريقة
querySelector
خارج الحلقة، يتم تجنب الحسابات المتكررة غير الضرورية۔
كن على دراية بنطاق المتغيرات
استخدم let
أو const
لضمان أن المتغيرات داخل الحلقة لها نطاق مناسب۔ نظرًا لأن var
يقتصر على نطاق الوظيفة، فقد يتسبب في سلوك غير متوقع۔
1// Using let
2for (let i = 0; i < 3; i++) {
3 console.log(i);
4}
5
6// Potential issue with var
7for (var i = 0; i < 3; i++) {
8 setTimeout(() => console.log(i), 1000); // 3, 3, 3
9}
10
11// Using let to avoid the issue
12for (let i = 0; i < 3; i++) {
13 setTimeout(() => console.log(i), 1000); // 0, 1, 2
14}
var
لها نطاق الوظيفة، لذلك بعد الحلقة تكون قيمةi
هي3
، وكل الدوال التي تُنفّذ بواسطةsetTimeout
تُرجع3
۔- باستخدام
let
، تشيرi
داخل دالة رد النداء لـsetTimeout
إلى قيمة جديدة لكل تكرار، وبالتالي تكون النتائج0, 1, 2
كما هو متوقع۔
حسِّن قابلية القراءة باستخدام الخروج المبكر
لتبسيط معالجة الحلقة، استخدم break
و continue
بشكل مناسب لتعزيز قابلية القراءة۔
1// Example using break
2for (let i = 0; i < 10; i++) {
3 if (i === 5) {
4 break; // Exit the loop
5 }
6 console.log(i);
7}
8
9// Example using continue
10for (let i = 0; i < 10; i++) {
11 if (i % 2 === 0) {
12 continue; // Skip to the next iteration
13 }
14 console.log(i);
15}
- استخدام
break
يتيح لك إنهاء معالجة الحلقة في منتصف الطريق، متجاوزًا جميع التكرارات التي تليها۔ - استخدام
continue
يتيح لك تخطي عملية الحلقة الحالية والانتقال إلى التكرار التالي۔
تجنب التداخل العميق
التداخل العميق يجعل الكود صعب القراءة، لذا حاول الحفاظ على تداخل بسيط باستخدام الخروج المبكر أو تقسيم الوظائف إلى وظائف أصغر۔
1// Deeply nested example
2for (let i = 0; i < 5; i++) {
3 for (let j = 0; j < 5; j++) {
4 if (i + j > 5) {
5 console.log(i, j);
6 }
7 }
8}
9
10// Improved using function decomposition
11function processPairs(i) {
12 for (let j = 0; j < 5; j++) {
13 if (i + j > 5) {
14 console.log(i, j);
15 }
16 }
17}
18
19for (let i = 0; i < 5; i++) {
20 processPairs(i);
21}
- في هذا المثال، يتم استخدام الدوال لتقليل التداخل۔
النظر في معالجة الأخطاء
إذا كان هناك احتمال لحدوث أخطاء داخل الحلقة، قم بتنفيذ معالجة الأخطاء بشكل صحيح۔
1const data = ["123", "abc", "456", "xyz"];
2
3// Without Error Handling
4for (const item of data) {
5 const result = parseInt(item);
6 console.log(`Parsed value: ${result}`);
7}
8
9// With Error Handling
10for (const item of data) {
11 try {
12 const result = parseInt(item);
13 if (isNaN(result)) {
14 throw new Error(`Invalid number: ${item}`);
15 }
16 console.log(`Parsed value: ${result}`);
17 } catch (error) {
18 console.error(`Error processing item: ${item}. ${error.message}`);
19 }
20}
- في هذا المثال، يتم التعامل مع الأخطاء أثناء معالجة البيانات غير الصالحة للكشف عن المشكلات والإبلاغ عنها۔
نقاط يجب ملاحظتها في المعالجة غير المتزامنة
عند التعامل مع المعالجة غير المتزامنة داخل الحلقات، يمكن أن يؤدي استخدام async/await
إلى كتابة كود مختصر وبديهي۔
1const urls = ["https://example.com/1", "https://example.com/2"];
2
3// Proper handling of asynchronous operations
4async function fetchUrls() {
5 for (const url of urls) {
6 const response = await fetch(url);
7 const data = await response.json();
8 console.log(data);
9 }
10}
11
12fetchUrls();
- يقوم هذا الكود بجلب عناوين URLs من المصفوفة
urls
بشكل غير متزامن واحدًا تلو الآخر ومعالجة النتائج بتنسيق JSON۔ استخدامasync/await
يُبسّط العمليات غير المتزامنة، حيث يتم جلب البيانات لكل URL على التوالي وإخراجها إلى وحدة التحكم۔
افهم الفرق بين عبارة for...of
و forEach()
في المعالجة غير المتزامنة.
1async function asyncTask(num) {
2 return new Promise(resolve => {
3 setTimeout(() => {
4 console.log(`Task ${num} done`);
5 resolve();
6 }, 100);
7 });
8}
9
10async function runWithForOf() {
11 console.log("Start for...of");
12 for (const num of [1, 2, 3]) {
13 await asyncTask(num);
14 }
15 console.log("End for...of");
16}
17
18async function runWithForEach() {
19 console.log("Start forEach");
20 [1, 2, 3].forEach(async num => {
21 await asyncTask(num);
22 });
23 console.log("End forEach");
24}
25
26async function executeExamples() {
27 await runWithForOf();
28 await runWithForEach();
29}
30
31executeExamples();
-
عند التعامل مع المعالجة غير المتزامنة في الحلقات، لاحظ الفروق في السلوك كما هو موضح في هذا المثال، بين استخدام
for...of
معasync/await
واستخدامforEach()
.۔ -
مع
for...of
، يتم تنفيذ الكود بشكل تسلسلي وينتظر عندawait
داخل الحلقة قبل المتابعة إلى التكرار التالي.۔ من ناحية أخرى، تقومforEach()
بتنفيذ المعالجة بالتوازي.۔
الخاتمة
عبارة for
في JavaScript أداة بسيطة لكنها قوية۔ من خلال الاستفادة من أفضل الممارسات التي تم تقديمها هنا، يمكنك كتابة كود فعال وسهل القراءة۔ انتبه لاختيار بناء الحلقات المناسبة، وإدارة النطاق، ومعالجة الأخطاء، وركز على كتابة كود قابل للصيانة بشكل كبير۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔