فلنفترض أنك تريد تشغيل دالة اسمها bounceBall
أربع مرات. كيف يمكنك ذلك؟ هل ستختار الطريقة التالية؟:
function bounceBall() { // bounce the ball here } bounceBall() bounceBall() bounceBall() bounceBall()
يمكن أن تكون الطريقة أعلاه مناسبة إذا كنت تريد تنفيذ الدالة بضع مرات. مالذي سيحدُث إن احتجت لتنفيذ الدالة bounceBall
مئة مرة؟
الطريقة الأفضل في هذه الحالة هي استخدام تعليمة التكرار الحلقي for
.
تعليمة التكرار الحلقي for
تنفّذ تعليمة التكرار الحلقي for
كتلة من التعليمات البرمجية بعدد المرات التي تريد. في ما يلي مثال على تنفيذ الدالة bounceBall
عشر مرات:
for (let i = 0; i < 10; i++) {
bounceBall()
}
تتكوّن التعليمة for
من أربعة أجزاء:
-
العبارة الابتدائية
initialExpression
-
الشرط
condition
-
عبارة الزيادة
incrementalExpression
-
والجملة
statement
for (initialExpression; condition; incrementExpression) {
statement
}
ستحتاج عندما تريد تنفيذ تعليمة تكرار حلقي إلى جملة برمجية Statement. الجملة هي كتلة الشفرة البرمجية التي تريد تنفيذها مرات عدّة. يمكنك كتابة أي شفرة ترغب بها مهما كان عدد أسطرها، كما يمكنك استخدام دوال.
تأخذ التعليمة for
الصيغة التالية عند استخدام الدالة bounceBall
في الجزء الخاصّ بالجملة:
for (initialExpression; condition; incrementExpression) {
bounceBall()
}
ستحتاج كذلك إلى تعريف عبارة ابتدائية Initial expression تبدأ بها تعليمة التكرار الحلقي. هذا هو الجزء الذي تعرّف فيه متغيرا. من المتعارف عليه تسمية المتغير الابتدائي في تعليمة for
بالحرف i
وإعطاؤه القيمة 0
.
هكذا تبدو صيغة for
عند تحديد عبارتها الابتدائية:
for (let i = 0; condition; incrementExpression) {
bounceBall()
}
نزيد قيمة المتغيّر (i
في مثالنا) - أو ننقُصه - بعد تنفيذ الحلقة التكرارية لأول مرة، وذلك عن طريق عبارة الزيادة Incremental expression. لزيادة قيمة المتغير i
بواحد نعيد إسناده بحيث يُصبح يساوي i + 1
أي بالعبارة i = i + 1
. تُختَصر العبارة i = i + 1
على ++i
والتي يكثُر استخدامها في حلقات التكرار. لنقص قيمة المتغير i
بواحد نعيد إسناده بحيث يُصبح يساوي i - 1
، أي بالعبارة i = i - 1
. تُختَصر العبارة i = i - 1
على --i
.
بالعودة إلى المثال مع الدالة bounceBall
فإننا زدنا المتغيّر i
في كل مرة بواحد. تصبح صيغة التعليمة for
على النحو التالي:
for (let i = 0; condition; i++) {
bounceBall()
}
لكن… هل يجدُر بي زيادة قيمة المتغيّر أم النقص منها؟
توجد الإجابة في الجزء الأخير من تعليمة التكرار الحلقي for
وهو الشرط. في حالة تحقّق الشرط - أي أن قيمته تساوي true
- فإن الجملة الموجودة في التعليمة for
تُنفَّذ وإلا فلا.
ينفّذ مفسر جافاسكريبت عبارة الزيادة incrementalExpression
مباشرة بعد تنفيذ الجملة statement
ثم يتحقّق مجدّدًا من أن قيمة الشرط تساوي true
فإن كان الأمر كذلك نفّذ الجملة statement
مرة أخرى. يعيد المفسّر الكرة إلى أن تصبح قيمة الشرط false
. حينها يتجاوز الحلقة التكرارية وينفّذ الشفرة التي تليها.
إن لم تكن تريد تنفيذ الحلقة فيمكنك جعل قيمة الشرط مساوية لـ false
منذ البداية:
// لن تُنفَّذ الحلقة التكرارية التالية نظرا لأن قيمة الشرط تساوي false
for (let i = 0; i < 0; i++) {
bounceBall()
const timesBounced = i + 1
console.log('The ball has bounced ' + timesBounced + ' times')
}
// ستُنفّذ الشفرة التالية فقط
console.log('next line of code')
ستكون نتيجة تنفيذ الشفرة أعلاه على النحو التالي:
next line of code
عندما تريد تنفيذ الحلقة التكرارية مرتين فستحتاج إلى تغيير الشرط بحيث تكون قيمته false
بعد تنفيذ عبارة الزيادة مرتين:
// ستُنفّذ الحلقة التكرارية التالية مرتين
for (let i = 0; i < 2; i++) {
bounceBall()
const timesBounced = i + 1
console.log('The ball has bounced ' + timesBounced + ' times')")
}
console.log('next line of code')
النتيجة:
The ball has bounced 1 times
The ball has bounced 2 times
next line of code
أما إذا أردت تشغيل الحلقة عشر مرات فسيتوجّب عليك تغيير الشرط بحيث تصبح قيمته false
بعد تنفيذ عبارة الزيادة عشر مرات.
// ستُنفّذ الحلقة التكرارية التالية عشر مرات
for (let i = 0; i < 10; i++) {
bounceBall()
const timesBounced = i + 1
console.log('The ball has bounced ' + timesBounced + ' times')")
}
console.log('next line of code')
النتيجة:
الحلقات غير المحدودة Infinite loops
نجد أنفسنا أمام حلقات غير محدودة عندما تكون قيمة الشرط في الحلقة التكرارية for
مساوية دائما لـtrue
، ممّا يتسبّب في تجمّد التبويب أو المتصفّح ونحتاج بالتالي لإغلاقه وإعادة تشغيله.
استخدام الحلقات التكرارية مع المصفوفات Arrays
في الواقع لن تحتاج كثيرا لاستخدام الحلقات التكرارية لتنفيذ دالة عشر مرات كما فعلنا مع الدالة bounceBall
السابقة. أغلب استخدامات الحلقات التكرارية هو مع المصفوفات أو الكائنات Objects.
يتمثّل التكرار عبر المصفوفة في المرور مرة واحدة على كل عنصُر في المصفوفة. بالإمكان استخدام طول المصفوفة (التابع length
) في الجزء الخاص بالشرط من تعليمة التكرار.
const fruitBasket = ['موزة', 'تفاحة', 'إجاصة']
// fruitBasket.length is 3
for (let i = 0; i < fruitBasket.length; i++) {
console.log("توجد " + fruitBasket[i] + " في السلة")
}
النتيجة:
توجد موزة في السلة
توجد تفاحة في السلة
توجد إجاصة في السلة
هناك طريقة بديلة وهي استخدام عبارة نقص بدلًا من عبارة الزيادة، وذلك بالبدء من نهاية المصفوفة في العبارة الابتدائية ضمن تعليمة التكرار:
for (let i = fruitBasket.length - 1; i >= 0; i--) {
console.log("توجد " + fruitBasket[i] + " في السلة")
}
النتيجة (لاحظ الفرق):
توجد إجاصة في السلة
توجد تفاحة في السلة
توجد موزة في السلة
المرور على المصفوفات بالحلقة for of
هناك طريقة ثالثة - أفضل بكثير - للمرور عبر مصفوفة، وهي استخدام تعليمة التكرار الحلقي for...of
وهي تعليمة جديدة من إضافات المعيار ES6. تُكتَب التعليمة بالصيغة التالية
const fruitBasket = ['موزة', 'تفاحة', 'إجاصة']
for (let fruit of fruitBasket) {
console.log("توجد " + fruit + " في السلة")
}
النتيجة:
توجد موزة في السلة
توجد تفاحة في السلة
توجد إجاصة في السلة
يُفضَّل استخدام التعليمة for ...of
بدلا من الطريقة التقليدية لاستخدام تعليمة التكرار الحلقي for
عند التعامل مع المصفوفات فهي تمرّ على المصفوفة لمرة واحدة فقط، كما لا تحتاج إلى طول المصفوفة؛ ممّا يجعل قراءة الشفرة وصيانتها أيسر بكثير.
يمكن استخدام التعليمة for ...of
مع أي كائن لديه الخاصيّة Symbol.iterator
. إن طبعت مصفوفة فارغة باستخدام التعليمة console.log
فسترى أن لديها خاصيّة باسم Synmbol.iterator
(ضمن المفتاح _proto_
).
العمليات المنطقية في الحلقات التكرارية
يمكنك استخدام if/else
أو أي عمليات منطقية أخرى داخلة حلقة for
التكرارية.
فلنفترض مثلا أن لديك مصفوفة بمجموعة من الأعداد وتريد إنشاء مصفوفة ثانية تتضمّن أعداد المصفوفة الأولى التي تصغُر 20.
حتى تصل إلى هدفك فيجب أن تمرّ أولا على عناصر المصفوفة الأولى بحلقة for
:
const numbers = [25, 22, 12, 56, 8, 18, 34];
for (let num of numbers) {
// سنكمل التعليمات بعد قليل
}
ثم نتحقّق ما إذا كان العنصُر الذي نمرّ عليه يقل عن 20. تصبح الشفرة كالتالي:
const numbers = [25, 22, 12, 56, 8, 18, 34];
for (let num of numbers) {
if (num < 20) {
// نكمل بعد قليل
}
}
إذا كان العنصُر أصغر من 20 نضيفه إلى مصفوفة أخرى. نستعمل التابع push
لهذا الغرض. تصبح الشفرة كالتالي (smallerThan20
هو اسم المصفوفة الثانية):
const numbers = [25, 22, 12, 56, 8, 18, 34];
let smallerThan20 = []
for (let num of numbers) {
if (num < 20) {
smallerThan20.push(num)
}
}
ترجمة - بتصرّف - للمقال Understanding for loops لصاحبه Zell Liew.
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.