{"id":"l-js-2-2","courseId":"javascript-fundamentals","lang":"ar","kind":"lesson","summary":"تكرّر العمل باستخدام for…of وحلقة for العدّادة وwhile، وتتوقّف مبكرًا بـ break وcontinue، وتستخدم نمط المُراكِم (accumulator) لحساب مجموع قائمة مصاريف.","html":"<p>حتى الآن، كل مثال في Pocket جمع عددًا ثابتًا من المصاريف: <code dir=\"ltr\">coffee + lunch + bus</code>. لكن الإنفاق الحقيقي قائمة تكبر كل يوم، ولا يمكنك كتابة <code dir=\"ltr\">+</code> لعناصر لم تصلك بعد. تحتاج إلى طريقة تقول بها “افعل هذا لكل واحد منها”، وهذه هي <strong>حلقة التكرار</strong> (loop).</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">قائمة نمرّ عليها</h2>\n<p>للقوائم درس كامل في القسم 3، لكنك تحتاج أساسياتها الآن. قائمة القيم بين أقواس مربّعة اسمها <strong>مصفوفة</strong> (array):</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"0\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">899</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// how many items</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// the first item: positions start at 0</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<h2 id=\"sec-2\" tabindex=\"-1\">for…of: افعل هذا لكل عنصر</h2>\n<p>تنفّذ <code dir=\"ltr\">for...of</code> كتلتها مرة لكل عنصر، مع اسم تختاره أنت يشير إلى العنصر الحالي:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"1\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">899</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amount</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> of</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amount;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(total);</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>تتبّعها خطوة بخطوة كما يفعل المحرّك. يبدأ <code dir=\"ltr\">total</code> من 0. الدورة الأولى: <code dir=\"ltr\">amount</code> تساوي 450، فيصبح <code dir=\"ltr\">total</code> يساوي 450. الدورة الثانية: <code dir=\"ltr\">amount</code> تساوي 1220، فيصبح <code dir=\"ltr\">total</code> يساوي 1670. ثم 1940، ثم 2839. لم يتبقَّ أي عنصر، فتنتهي الحلقة ويطبع السطر التالي المجموع.</p>\n<p>يُسمّى هذا الشكل <strong>نمط المُراكِم</strong> (accumulator pattern): صرّح بنتيجة قبل الحلقة، وحدّثها داخلها، واستخدمها بعدها. وهو وراء المجاميع والأعداد والقيم القصوى ومعظم الملخّصات التي ستكتبها. واستخدام <code dir=\"ltr\">const amount</code> سليم مع أنها تتغيّر في كل دورة: فكل دورة تُنشئ <code dir=\"ltr\">amount</code> جديدة، ولا يُعاد إسنادها أبدًا.</p>\n<p>وتعمل <code dir=\"ltr\">for...of</code> أيضًا مع النصوص، حرفًا حرفًا: <code dir=\"ltr\">for (const ch of &quot;Pocket&quot;)</code>.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">حلقة for العدّادة</h2>\n<p>أحيانًا تحتاج إلى <strong>الموضع</strong> إلى جانب العنصر، مثلًا لتطبع “1. Coffee”. لحلقة <code dir=\"ltr\">for</code> الكلاسيكية ثلاثة أجزاء بين قوسيها:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"2\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> labels</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Lunch\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bus\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> i </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; i </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> labels.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; i</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">++</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">i</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}. ${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">labels</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">[</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">i</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">]</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 660 230\" role=\"img\" aria-labelledby=\"l-js-2-2-t1\"><defs><marker id=\"arrow-l-js-2-2-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-js-2-2-t1\">تنفّذ حلقة for جزء البداية مرة واحدة، ثم تكرّر: فحص الشرط، ثم تنفيذ الجسم، ثم تنفيذ التحديث، حتى يصبح الشرط خاطئًا فتخرج من الحلقة.</title>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"90\" width=\"140\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"90\" y=\"120\" text-anchor=\"middle\">let i = 0</text>\n  <rect class=\"d-box-accent\" x=\"220\" y=\"90\" width=\"190\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"315\" y=\"120\" text-anchor=\"middle\">i &lt; labels.length?</text>\n  <rect class=\"d-box\" x=\"470\" y=\"20\" width=\"170\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"555\" y=\"50\" text-anchor=\"middle\">نفّذ الجسم</text>\n  <rect class=\"d-box\" x=\"470\" y=\"160\" width=\"170\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"555\" y=\"190\" text-anchor=\"middle\">i++</text>\n  <rect class=\"d-box-success\" x=\"220\" y=\"175\" width=\"120\" height=\"40\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"280\" y=\"200\" text-anchor=\"middle\">خروج</text>\n  <path class=\"d-arrow\" d=\"M160 115 L216 115\" marker-end=\"url(#arrow-l-js-2-2-1)\"/>\n  <path class=\"d-arrow\" d=\"M400 95 L466 55\" marker-end=\"url(#arrow-l-js-2-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"425\" y=\"62\" text-anchor=\"middle\">true</text>\n  <path class=\"d-arrow\" d=\"M555 70 L555 156\" marker-end=\"url(#arrow-l-js-2-2-1)\"/>\n  <path class=\"d-arrow\" d=\"M470 180 L414 135\" marker-end=\"url(#arrow-l-js-2-2-1)\"/>\n  <path class=\"d-arrow\" d=\"M280 140 L280 171\" marker-end=\"url(#arrow-l-js-2-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"312\" y=\"162\" text-anchor=\"middle\">false</text>\n  <text class=\"d-label-muted\" x=\"90\" y=\"160\" text-anchor=\"middle\">مرة واحدة</text>\n</svg><figcaption>أجزاء حلقة for الثلاثة وترتيب تنفيذها</figcaption></figure>\n<p>جزء البداية، <code dir=\"ltr\">let i = 0</code>، يُنفَّذ مرة واحدة. ثم قبل كل دورة يُفحص الشرط <code dir=\"ltr\">i &lt; labels.length</code>؛ فإن كان صحيحًا نُفّذ الجسم، ثم يضيف التحديث <code dir=\"ltr\">i++</code> واحدًا إلى <code dir=\"ltr\">i</code>. وحين يصبح الشرط خاطئًا تنتهي الحلقة. مع ثلاث تسميات، تأخذ <code dir=\"ltr\">i</code> القيم 0 و1 و2، وهي الفهارس الصالحة بالضبط.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>الفارق بواحد (off by one)</span></p>\n<p><code dir=\"ltr\">i &lt;= labels.length</code> تُنفّذ دورة إضافية تكون فيها <code dir=\"ltr\">i</code> تساوي 3، و<code dir=\"ltr\">labels[3]</code> تساوي <code dir=\"ltr\">undefined</code>. الفهارس الصالحة تمتد من 0 إلى <code dir=\"ltr\">length - 1</code>، لذلك يكون الشرط <code dir=\"ltr\">i &lt; length</code>. وحين لا تحتاج إلى الفهرس، استخدم <code dir=\"ltr\">for...of</code> فلا يمكن أن يقع هذا الخطأ.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">while: كرّر حتى يتغيّر شيء ما</h2>\n<p>حلقة <code dir=\"ltr\">while</code> ليس فيها إلا شرط. إنها للحالات التي تعرف فيها متى تتوقّف، لكن لا تعرف كم دورة سيستغرق ذلك. كم يومًا تستطيع أن تشتري قهوة بـ 4.50 دولار بميزانية قدرها 20 دولارًا؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"3\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> balance </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> coffee</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> days </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">while</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (balance </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">>=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> coffee) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  balance </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> coffee;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  days</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">++</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">days</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">} coffees, ${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">balance</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">} cents left`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>كل دورة تُنقص <code dir=\"ltr\">balance</code>، فيصبح الشرط خاطئًا في النهاية. ولو لم يكن في الجسم ما يقترب من المخرج، كأن تنسى <code dir=\"ltr\">balance -= coffee</code>، لبقي الشرط صحيحًا إلى الأبد. وهذه <strong>حلقة لا نهائية</strong> (infinite loop): تتجمّد الصفحة، ويعرض عليك المتصفّح في النهاية إيقاف السكربت. وحين يتجمّد تبويب أثناء تدرّبك، ابحث عن حلقة لا يتغيّر شرطها أبدًا.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">break وcontinue</h2>\n<p>كلمتان مفتاحيتان تغيّران مسار الحلقة من داخلها:</p>\n<ul>\n<li><code dir=\"ltr\">break</code> تُنهي الحلقة فورًا.</li>\n<li><code dir=\"ltr\">continue</code> تتخطّى باقي هذه الدورة وتنتقل إلى التالية.</li>\n</ul>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"4\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">300</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">899</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> budget</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> running </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amount</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> of</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts) {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  if</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    continue</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// a refund: not spending, skip it</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  running </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amount;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  if</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (running </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> budget) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`Budget passed at an expense of ${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">amount</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    break</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// no need to look further</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(running);</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p>تتبّعها: يُضاف 450، ثم يُتخطّى -300، ثم يرفع 1220 المجموع إلى 1670، ثم يرفعه 270 إلى 1940، ثم يدفعه 899 إلى 2839، وهذا يتجاوز الميزانية، فتُطبع الرسالة وتتوقّف الحلقة.</p>\n<h2 id=\"sec-6\" tabindex=\"-1\">أن ترى ما تفعله الحلقة</h2>\n<p>الحلقات هي المكان الذي يفقد فيه المبتدئون أثر ما يفعله البرنامج أكثر من أي مكان آخر، لأن الأسطر نفسها تُنفَّذ مرات كثيرة بقيم مختلفة. والعلاج أن تجعل الحلقة تُريك. ضع <code dir=\"ltr\">console.log</code> في أول الجسم يطبع كل متغيّر له علاقة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"5\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> i </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; i </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; i</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">++</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({ i, amount: amounts[i], totalBefore: total });</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts[i];</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"final\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, total);</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>كل دورة تطبع سطرًا واحدًا، فتستطيع أن تقارن ما حدث فعلًا بما توقّعته، وتجد أول دورة يختلفان فيها. تلك الدورة هي مكان الخطأ. ووضع القيم داخل <code dir=\"ltr\">{ }</code> يطبعها مع أسمائها، فلا تحتاج إلى تخمين أيّ رقم هو أيّ متغيّر. المطوّرون المحترفون يفعلون هذا بالضبط كل يوم؛ وفي القسم 5 ستتعلّم فعله أيضًا باستخدام مصحّح الأخطاء (debugger) في DevTools.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">نصيحة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>اختر الحلقة بحسب ما يتحكّم فيها</span></p>\n<p>المرور على قائمة: <code dir=\"ltr\">for...of</code>. تحتاج الموضع أيضًا: <code dir=\"ltr\">for</code> العدّادة. التوقّف يعتمد على شرط متغيّر لا على قائمة: <code dir=\"ltr\">while</code>. في القسم 3 ستتعرّف إلى دوال المصفوفات مثل <code dir=\"ltr\">map</code> و<code dir=\"ltr\">filter</code>، التي تحلّ محلّ كثير من الحلقات المكتوبة يدويًا، لكنها مبنية على هذه الأفكار نفسها بالضبط.</p>\n</aside>\n<p>الحلقات والشروط معًا تتيح لك كتابة منطق حقيقي من الآن. ولكي تعيد استخدام هذا المنطق بدلًا من نسخه، تحتاج إلى دوالّك الخاصة، وهذا موضوع الدرس التالي.</p>\n","toc":[{"id":"sec-1","text":"قائمة نمرّ عليها","level":2},{"id":"sec-2","text":"for…of: افعل هذا لكل عنصر","level":2},{"id":"sec-3","text":"حلقة for العدّادة","level":2},{"id":"sec-4","text":"while: كرّر حتى يتغيّر شيء ما","level":2},{"id":"sec-5","text":"break وcontinue","level":2},{"id":"sec-6","text":"أن ترى ما تفعله الحلقة","level":2}],"takeaways":["<code dir=\"ltr\">for...of</code> تمرّ على كل عنصر في القائمة بالترتيب، وهي حلقة التكرار الافتراضية لـ “افعل هذا لكل مصروف”.","حلقة <code dir=\"ltr\">for</code> العدّادة تعطيك فهرسًا، وتحتاجه حين يهمّ الموضع؛ والفهارس الصالحة تمتد من 0 إلى <code dir=\"ltr\">length - 1</code>.","<code dir=\"ltr\">while</code> تكرّر ما دام الشرط صحيحًا، لذلك يجب أن يجعله شيء داخل الحلقة خاطئًا في النهاية.","نمط المُراكِم (ابدأ من 0، وأضف داخل الحلقة، واستخدم الناتج بعدها) يحوّل قائمة إلى مجموع واحد."],"further":[{"title":"Loops and iteration (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration"},{"title":"for...of (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of"}],"quiz":[{"q":"<p>ماذا يطبع هذا الكود؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">400</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">900</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">250</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> a</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> of</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(total);</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">1550</code>","why":"هذا يتطلّب <code dir=\"ltr\">total += a</code>. أما <code dir=\"ltr\">=</code> وحدها فتستبدل المجموع بكل مبلغ بدلًا من أن تضيفه إليه."},{"text":"<code dir=\"ltr\">250</code>","why":"صحيح. كل دورة تكتب فوق <code dir=\"ltr\">total</code>، فينتهي حاملًا المبلغ الأخير."},{"text":"<code dir=\"ltr\">400</code>","why":"تستمر الحلقة بعد العنصر الأول، وكل دورة تعيد إسناد <code dir=\"ltr\">total</code>."},{"text":"<code dir=\"ltr\">0</code>","why":"يُعاد إسناد <code dir=\"ltr\">total</code> داخل الحلقة، فلا يبقى حاملًا قيمته الابتدائية."}],"answer":1},{"q":"<p><code dir=\"ltr\">const days = [&quot;Mon&quot;, &quot;Tue&quot;, &quot;Wed&quot;];</code> أيّ حلقة لا ترمي أي خطأ لكنها تطبع <code dir=\"ltr\">undefined</code> مرة واحدة في النهاية؟</p>","options":[{"text":"<code dir=\"ltr\">for (let i = 0; i &lt; days.length; i++) console.log(days[i]);</code>","why":"هذه هي الحلقة العدّادة الصحيحة. إنها تتوقّف بعد الفهرس 2، وهو آخر فهرس صالح."},{"text":"<code dir=\"ltr\">for (const d of days) console.log(d);</code>","why":"<code dir=\"ltr\">for...of</code> تمرّ على العناصر الموجودة فعلًا فقط، فلا يمكنها تجاوز النهاية."},{"text":"<code dir=\"ltr\">for (let i = 0; i &lt;= days.length; i++) console.log(days[i]);</code>","why":"صحيح. <code dir=\"ltr\">&lt;=</code> تسمح لـ <code dir=\"ltr\">i</code> بأن تبلغ 3، و<code dir=\"ltr\">days[3]</code> غير موجود، فيُطبع <code dir=\"ltr\">undefined</code>. وخطأ “الفارق بواحد” هذا شائع جدًا."}],"answer":2},{"q":"<p>متى تكون <code dir=\"ltr\">while</code> أنسب من <code dir=\"ltr\">for...of</code>؟</p>","options":[{"text":"حين لا تعرف مسبقًا كم مرة ستحتاج إلى التكرار، بل تعرف فقط متى تتوقّف.","why":"صحيح. مثلًا، “استمر في طرح الإنفاق اليومي حتى ينفد الرصيد” لا توجد فيه قائمة تمرّ عليها."},{"text":"حين تريد المرور على كل عنصر في قائمة.","why":"هذه بالضبط مهمة <code dir=\"ltr\">for...of</code>، التي لا يمكنها تجاوز النهاية ولا نسيان التقدّم."},{"text":"حين يكون جسم الحلقة أكثر من سطر واحد.","why":"يمكن لأي حلقة أن يكون جسمها بأي طول. والاختيار يعتمد على ما يتحكّم في التكرار."}],"answer":0},{"q":"<p>داخل حلقة تمرّ على المصاريف، ماذا تفعل <code dir=\"ltr\">continue</code>؟</p>","options":[{"text":"تُنهي الحلقة كلها فورًا.","why":"هذه <code dir=\"ltr\">break</code>. أما <code dir=\"ltr\">continue</code> فتتخطّى باقي الدورة الحالية فقط."},{"text":"تتخطّى باقي الدورة الحالية وتنتقل إلى العنصر التالي.","why":"صحيح. إنها مفيدة لتجاهل العناصر غير المعنية، مثل المبالغ المستردّة، دون أن تضع باقي الجسم داخل <code dir=\"ltr\">if</code>."},{"text":"تعيد تشغيل الحلقة من العنصر الأول.","why":"الحلقات لا ترجع إلى الوراء من تلقاء نفسها. <code dir=\"ltr\">continue</code> تتقدّم إلى العنصر التالي."}],"answer":1}],"exercise":{"kind":"web","mode":"js","starter":{"js":"const amounts = [450, -300, 1220, 270, 899];\n\n// Total of all spending; negative amounts are refunds, skip them\nfunction totalSpent(amounts) {\n  let total = 0;\n  // loop here\n  return total;\n}\n\n// How many amounts are at least `minimum`\nfunction countAtLeast(amounts, minimum) {\n  return 0;\n}\n\n// The index of the expense at which the running total of spending\n// first goes over `budget`, or -1 if it never does (skip refunds here too)\nfunction firstOverBudget(amounts, budget) {\n  return -1;\n}\n\nconsole.log(totalSpent(amounts), countAtLeast(amounts, 500), firstOverBudget(amounts, 2000));\n"},"solution":{"js":"const amounts = [450, -300, 1220, 270, 899];\n\nfunction totalSpent(amounts) {\n  let total = 0;\n  for (const amount of amounts) {\n    if (amount < 0) {\n      continue;\n    }\n    total += amount;\n  }\n  return total;\n}\n\nfunction countAtLeast(amounts, minimum) {\n  let count = 0;\n  for (const amount of amounts) {\n    if (amount >= minimum) {\n      count++;\n    }\n  }\n  return count;\n}\n\nfunction firstOverBudget(amounts, budget) {\n  let running = 0;\n  for (let i = 0; i < amounts.length; i++) {\n    if (amounts[i] < 0) {\n      continue;\n    }\n    running += amounts[i];\n    if (running > budget) {\n      return i;\n    }\n  }\n  return -1;\n}\n\nconsole.log(totalSpent(amounts), countAtLeast(amounts, 500), firstOverBudget(amounts, 2000));\n"},"checks":[{"id":"total","test":"return totalSpent([450, -300, 1220, 270, 899]) === 2839 && totalSpent([]) === 0 && totalSpent([100, 200]) === 300;\n"},{"id":"count","test":"return countAtLeast([450, -300, 1220, 270, 899], 500) === 2 && countAtLeast([500, 499, 501], 500) === 2 && countAtLeast([], 1) === 0;\n"},{"id":"first-over","test":"return firstOverBudget([450, -300, 1220, 270, 899], 2000) === 4 && firstOverBudget([3000], 2000) === 0;\n"},{"id":"never-over","test":"return firstOverBudget([100, 200], 2000) === -1 && firstOverBudget([1000, 1000], 2000) === -1 && firstOverBudget([], 10) === -1;\n"}],"title":"مُرّ على مصاريف Pocket","prompt":"<p>تستلم كل دالة <code dir=\"ltr\">amounts</code>، وهي مصفوفة مبالغ بالسنتات، والأرقام السالبة فيها مبالغ مستردّة. أكمل:</p>\n<ul>\n<li><code dir=\"ltr\">totalSpent(amounts)</code>: مجموع كل الإنفاق، مع تخطّي المبالغ المستردّة.</li>\n<li><code dir=\"ltr\">countAtLeast(amounts, minimum)</code>: عدد المبالغ الأكبر من <code dir=\"ltr\">minimum</code> أو المساوية له.</li>\n<li><code dir=\"ltr\">firstOverBudget(amounts, budget)</code>: <strong>فهرس</strong> المصروف الذي يتجاوز عنده مجموع الإنفاق المتراكم <code dir=\"ltr\">budget</code> لأول مرة (مع تخطّي المبالغ المستردّة)، أو <code dir=\"ltr\">-1</code> إن لم يتجاوزها أبدًا.</li>\n</ul>\n","hints":["كل واحدة منها تتبع نمط المُراكِم. صرّح بنتيجة قبل الحلقة، وحدّثها داخلها، وأرجعها بعدها.","<code dir=\"ltr\">if (amount &lt; 0) { continue; }</code> تتخطّى المبلغ المستردّ. وفي <code dir=\"ltr\">firstOverBudget</code> تحتاج إلى الموضع، فاستخدم الحلقة العدّادة: <code dir=\"ltr\">for (let i = 0; i &lt; amounts.length; i++)</code>.","في <code dir=\"ltr\">firstOverBudget</code>، بمجرّد أن يصبح <code dir=\"ltr\">running &gt; budget</code>، فإن <code dir=\"ltr\">return i;</code> تُنهي الدالة (والحلقة معها). وبعد الحلقة اكتب <code dir=\"ltr\">return -1;</code>."],"explanation":"<p>تشترك الدوال الثلاث في شكل واحد: متغيّر يُهيَّأ قبل الحلقة، ويتغيّر داخلها، ويُرجَع بعدها. وتتيح لك <code dir=\"ltr\">continue</code> تخطّي المبالغ المستردّة دون أن تضع باقي الجسم داخل <code dir=\"ltr\">if</code> أخرى. أما <code dir=\"ltr\">firstOverBudget</code> فتحتاج إلى الموضع، لذلك تستخدم الحلقة العدّادة مع <code dir=\"ltr\">i &lt; amounts.length</code>، وهو نطاق الفهارس الصالحة بالضبط. والإرجاع من داخل الحلقة يوقفها عند أول تطابق، و<code dir=\"ltr\">return -1</code> بعد الحلقة لا تُنفَّذ إلا حين لا يوجد أي تطابق. وإنفاق الميزانية بالضبط ليس تجاوزًا لها، لذلك تُرجع <code dir=\"ltr\">[1000, 1000]</code> مع ميزانية 2000 القيمة -1.</p>\n","checkLabels":{"total":"<code dir=\"ltr\">totalSpent</code> تجمع الإنفاق وتتخطّى المبالغ المستردّة","count":"<code dir=\"ltr\">countAtLeast</code> تعدّ المبالغ التي تساوي الحدّ الأدنى أو تزيد عليه","first-over":"<code dir=\"ltr\">firstOverBudget</code> تُرجع الفهرس الذي تُتجاوز عنده الميزانية لأول مرة","never-over":"<code dir=\"ltr\">firstOverBudget</code> تُرجع -1 حين لا تُتجاوز الميزانية أبدًا"}},"words":641,"readMinutes":4}