{"id":"l-js-2-3","courseId":"javascript-fundamentals","lang":"ar","kind":"lesson","summary":"تكتب دوالّك الخاصة بأسلوب التصريح وبأسلوب الدوال السهمية، وتمرّر الوسائط إليها وتستخرج النتائج منها بـ return، وتمنح المعاملات قيمًا افتراضية، وتمرّر الدوال إلى دوال أخرى.","html":"<p>في الدرسين السابقين أكملت أجسام دوال كُتبت لك. والآن تكتب دوالّك بنفسك. <strong>الدالة</strong> (function) قطعة من البرنامج لها اسم ويمكن إعادة استخدامها: تكتب الخطوات مرة واحدة وتنفّذها متى احتجت، بمدخلات مختلفة. يُنسّق Pocket المبالغ المالية في أماكن كثيرة؛ ودون الدوال ستنسخ <code dir=\"ltr\">(cents / 100).toFixed(2)</code> في كل منها، ثم تُصلح كل نسخة حين يتغيّر التنسيق.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">التصريح بدالة واستدعاؤها</h2>\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\">function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> formatMoney</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">cents</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\"> dollars</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (cents </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">/</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toFixed</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `$${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">dollars</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>\n<span class=\"line\"></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:#8250DF;--shiki-dark:#D2A8FF\">formatMoney</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>\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:#8250DF;--shiki-dark:#D2A8FF\">formatMoney</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></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>الأسطر الخمسة الأولى <strong>تصريح دالة</strong> (function declaration). إنها لا تنفّذ شيئًا؛ بل تُنشئ دالة اسمها <code dir=\"ltr\">formatMoney</code> وتحفظ خطواتها. و<code dir=\"ltr\">cents</code> <strong>معامل</strong> (parameter)، أي اسم لمُدخل ليست له قيمة بعد.</p>\n<p>أما <code dir=\"ltr\">formatMoney(1220)</code> فهو <strong>استدعاء</strong> (call). والقيمة بين القوسين، <code dir=\"ltr\">1220</code>، <strong>وسيط</strong> (argument). حين يصل المحرّك إلى الاستدعاء، يوقف السطر الحالي مؤقتًا، ويقفز إلى داخل الدالة و<code dir=\"ltr\">cents</code> تشير إلى 1220، فينفّذ الجسم، ثم يعود حين يصل إلى <code dir=\"ltr\">return</code>. بعدها يُستبدل تعبير الاستدعاء بالقيمة المُعادة، <code dir=\"ltr\">&quot;$12.20&quot;</code>، فتطبعها <code dir=\"ltr\">console.log</code>.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 660 220\" role=\"img\" aria-labelledby=\"l-js-2-3-t1\"><defs><marker id=\"arrow-l-js-2-3-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-3-t1\">الاستدعاء formatMoney(1220) يمرّر 1220 إلى المعامل cents. يُنفَّذ جسم الدالة ويُعيد النص $12.20، الذي يحلّ محلّ الاستدعاء في السطر الأصلي.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"30\" width=\"250\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"145\" y=\"60\" text-anchor=\"middle\">formatMoney(1220)</text>\n  <rect class=\"d-box-primary\" x=\"380\" y=\"20\" width=\"260\" height=\"170\" rx=\"12\"/>\n  <text class=\"d-label-strong\" x=\"510\" y=\"46\" text-anchor=\"middle\">function formatMoney</text>\n  <text class=\"d-code\" x=\"510\" y=\"82\" text-anchor=\"middle\">cents = 1220</text>\n  <text class=\"d-code\" x=\"510\" y=\"114\" text-anchor=\"middle\">dollars = \"12.20\"</text>\n  <text class=\"d-code\" x=\"510\" y=\"150\" text-anchor=\"middle\">return \"$12.20\"</text>\n  <path class=\"d-arrow\" d=\"M270 50 L376 70\" marker-end=\"url(#arrow-l-js-2-3-1)\"/>\n  <text class=\"d-label-muted\" x=\"322\" y=\"46\" text-anchor=\"middle\">الوسيط</text>\n  <path class=\"d-arrow\" d=\"M376 150 L200 150 L160 84\" marker-end=\"url(#arrow-l-js-2-3-1)\"/>\n  <text class=\"d-label-muted\" x=\"270\" y=\"172\" text-anchor=\"middle\">القيمة المُعادة</text>\n</svg><figcaption>الاستدعاء يُرسل الوسائط إلى الداخل ويستعيد القيمة المُعادة</figcaption></figure>\n<p>يمكن أن يكون للدالة عدّة معاملات تفصل بينها فواصل، وتُطابَق الوسائط معها حسب الموضع: الوسيط الأول يذهب إلى المعامل الأول، وهكذا.</p>\n<p>لـ <code dir=\"ltr\">return</code> وظيفتان: تحدّد النتيجة، وتُنهي الدالة في مكانها. أي سطر بعد <code dir=\"ltr\">return</code> في الكتلة نفسها لا يُنفَّذ أبدًا. وإذا انتهت الدالة دون أن تصل إلى <code dir=\"ltr\">return</code>، فإن قيمة الاستدعاء تكون <code dir=\"ltr\">undefined</code>.</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>الطباعة بدلًا من الإرجاع</span></p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"1\"><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\">function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> toCents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">dollars</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\">(Math.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">round</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(dollars </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)); </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// shows the answer...</span></span>\n<span class=\"line\"><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\"> total</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> toCents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4.1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> toCents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12.2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">); </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// ...but returns undefined: NaN</span></span></code></pre></div>\n<p><code dir=\"ltr\">console.log</code> تعرض القيمة فقط؛ ولا تُعيد شيئًا إلى من استدعى الدالة. الدالة التي تحسب شيئًا يجب أن تُرجعه بـ <code dir=\"ltr\">return</code>، والمُستدعي هو الذي يقرّر إن كان سيطبعه.</p>\n</aside>\n<h2 id=\"sec-2\" tabindex=\"-1\">المعاملات الافتراضية</h2>\n<p>إذا استدعيت دالة بوسائط أقل من معاملاتها، تكون المعاملات الناقصة <code dir=\"ltr\">undefined</code>. و<strong>المعامل الافتراضي</strong> (default parameter) يمنحها قيمة معقولة بدلًا من ذلك:</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\">function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> formatMoney</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">cents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">symbol</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</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\">  return</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">symbol</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">cents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toFixed</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</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>\n<span class=\"line\"></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:#8250DF;--shiki-dark:#D2A8FF\">formatMoney</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>\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:#8250DF;--shiki-dark:#D2A8FF\">formatMoney</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:#0A3069;--shiki-dark:#A5D6FF\">\"€\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>تُستخدم القيمة الافتراضية حين يكون الوسيط مفقودًا أو <code dir=\"ltr\">undefined</code>، وحينها فقط. أما تمرير <code dir=\"ltr\">0</code> أو <code dir=\"ltr\">&quot;&quot;</code> أو <code dir=\"ltr\">null</code> فيُعدّ وسيطًا حقيقيًا.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">الدوال السهمية</h2>\n<p>هناك طريقة ثانية أقصر لكتابة الدوال، هي <strong>الدالة السهمية</strong> (arrow function). إنها قيمة، لذلك تخزّنها في <code dir=\"ltr\">const</code>:</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\">const</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> toCents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#953800;--shiki-dark:#FFA657\">dollars</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Math.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">round</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(dollars </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</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:#8250DF;--shiki-dark:#D2A8FF\"> isBig</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#953800;--shiki-dark:#FFA657\">cents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> cents </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">>=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 10000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></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:#8250DF;--shiki-dark:#D2A8FF\">toCents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12.2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">), </span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">isBig</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toCents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">120</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\">return</code>: فقيمة التعبير تُعاد تلقائيًا. وحين تحتاج إلى عدّة تعليمات، استخدم الأقواس المعقوفة، وعندها تصبح <code dir=\"ltr\">return</code> مطلوبة من جديد:</p>\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:#8250DF;--shiki-dark:#D2A8FF\"> budgetLeft</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#953800;--shiki-dark:#FFA657\">budget</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">spent</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </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:#CF222E;--shiki-dark:#FF7B72\">  const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> left</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> budget </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> spent;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> left </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ?</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> left </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:#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:#8250DF;--shiki-dark:#D2A8FF\">budgetLeft</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2200</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p>أيّ الأسلوبين تستخدم؟ كلاهما منتشر في الكود الحقيقي. والاختيار الافتراضي الشائع، الذي تتبعه هذه الدورة: <strong>التصريح للدوال المسمّاة في المستوى الأعلى، والدوال السهمية للدوال القصيرة التي تُمرَّر إلى دوال أخرى</strong>. وهناك فرق عملي واحد: تصريحات الدوال <strong>تُرفع</strong> (hoisting)، أي يمكنك استدعاؤها في سطر يسبق مكان كتابتها. أما الدالة السهمية المخزّنة في <code dir=\"ltr\">const</code> فلا توجد إلا بعد أن يُنفَّذ سطرها.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">الدوال قيم</h2>\n<p>الدالة في JavaScript قيمة مثل الرقم أو النص. يمكنك تخزينها، ويمكنك تمريرها إلى دالة أخرى بصفتها وسيطًا. وهذه الفكرة وراء جزء كبير من JavaScript الحديثة:</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\">function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> applyToAll</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">amounts</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">transform</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\"> results</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:#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\">    results.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">push</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">transform</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:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> results;</span></span>\n<span class=\"line\"><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\">const</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> formatMoney</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#953800;--shiki-dark:#FFA657\">cents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `$${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">cents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toFixed</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</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\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">applyToAll</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\">], formatMoney));</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:#8250DF;--shiki-dark:#D2A8FF\">applyToAll</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:#953800;--shiki-dark:#FFA657\">c</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> c </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p><code dir=\"ltr\">applyToAll</code> لا تعرف ما تفعله <code dir=\"ltr\">transform</code> ولا يهمّها ذلك؛ إنها تستدعيها مرة لكل عنصر وتجمع النتائج باستخدام <code dir=\"ltr\">push</code>، التي تضيف عنصرًا إلى نهاية المصفوفة. والدالة التي تُمرَّر بهذه الطريقة تُسمّى <strong>callback</strong> (دالة استدعاء راجع). لاحظ أنك تمرّر <code dir=\"ltr\">formatMoney</code> دون أقواس: فأنت تسلّم الدالة نفسها، لا تستدعيها. وللمصفوفات أداة مدمجة تفعل هذا بالضبط، اسمها <code dir=\"ltr\">map</code>، وسيضعها القسم 3 موضع العمل.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">دوال صغيرة ونقية</h2>\n<p>لاحظ ما تشترك فيه كل الدوال المساعدة في هذا الدرس: إنها لا تستخدم إلا معاملاتها، وتُرجع نتيجة، ولا تغيّر شيئًا خارجها. الدالة من هذا النوع تُسمّى <strong>نقية</strong> (pure). أعطها الوسائط نفسها تُعِد الإجابة نفسها في كل مرة، فتستطيع اختبارها بسطر واحد، وإعادة استخدامها في أي مكان، والثقة بها دون أن تقرأ جسمها مجددًا.</p>\n<p>ليست كل دالة قادرة على أن تكون نقية. لا بدّ لشيء ما في النهاية أن يطبع على الشاشة أو يحفظ البيانات. والعادة التي تُبقي البرامج تحت السيطرة هي أن تُجري الحسابات في دوال صغيرة نقية، وأن تُبقي الطباعة والحفظ في أماكن قليلة ذات أسماء واضحة. ويتبع Pocket هذا الفصل حتى التطبيق النهائي.</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\">formatMoney</code> و<code dir=\"ltr\">toCents</code> و<code dir=\"ltr\">isBig</code> و<code dir=\"ltr\">budgetLeft</code>: فعلٌ للدوال التي تفعل أو تحسب شيئًا، و<code dir=\"ltr\">is</code>/<code dir=\"ltr\">has</code> للدوال التي تُرجع قيمة منطقية. الأسماء الجيدة تجعلك تقرأ <code dir=\"ltr\">if (isBig(amount))</code> كأنها جملة.</p>\n</aside>\n<p>الدوال تُنشئ داخلها عالمًا صغيرًا من الأسماء خاصًا بها. وعلاقة هذا العالم بالكود المحيط به تُسمّى النطاق (scope)، وهي موضوع الدرس التالي.</p>\n","toc":[{"id":"sec-1","text":"التصريح بدالة واستدعاؤها","level":2},{"id":"sec-2","text":"المعاملات الافتراضية","level":2},{"id":"sec-3","text":"الدوال السهمية","level":2},{"id":"sec-4","text":"الدوال قيم","level":2},{"id":"sec-5","text":"دوال صغيرة ونقية","level":2}],"takeaways":["الدالة تحزم خطوات تحت اسم واحد؛ والمعاملات (parameters) هي المدخلات التي تعلنها الدالة، أما الوسائط (arguments) فهي القيم التي تمرّرها حين تستدعيها.","<code dir=\"ltr\">return</code> تُنهي الدالة وتُعيد قيمة؛ والدالة التي لا تحتوي على <code dir=\"ltr\">return</code> تُعيد <code dir=\"ltr\">undefined</code>.","الدوال السهمية (<code dir=\"ltr\">(x) =&gt; x * 2</code>) صياغة أقصر؛ ومع الأقواس المعقوفة تحتاج إلى <code dir=\"ltr\">return</code> صريحة.","المعاملات الافتراضية (<code dir=\"ltr\">symbol = &quot;$&quot;</code>) تُطبَّق حين يكون الوسيط مفقودًا أو <code dir=\"ltr\">undefined</code>.","الدوال قيم، لذلك يمكنك تخزينها في متغيّرات وتمريرها إلى دوال أخرى."],"further":[{"title":"Functions (MDN guide)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions"},{"title":"Arrow function expressions (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions"},{"title":"Default parameters (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters"}],"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:#8250DF;--shiki-dark:#D2A8FF\"> double</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#953800;--shiki-dark:#FFA657\">n</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </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\">  n </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2</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:#8250DF;--shiki-dark:#D2A8FF\">double</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">undefined</code>","why":"صحيح. الجسم المحاط بأقواس معقوفة دون <code dir=\"ltr\">return</code> يُعيد <code dir=\"ltr\">undefined</code>. اكتب <code dir=\"ltr\">(n) =&gt; n * 2</code> أو أضف <code dir=\"ltr\">return n * 2;</code>."},{"text":"<code dir=\"ltr\">8</code>","why":"الجسم يحسب 8 ثم يرميه. مع الأقواس المعقوفة، تحتاج الدالة السهمية إلى <code dir=\"ltr\">return</code> صريحة."},{"text":"<code dir=\"ltr\">n * 2</code>","why":"تحسب JavaScript التعبيرات؛ ولا تُعيد أبدًا نصّها المكتوب."}],"answer":0},{"q":"<p>الدالة <code dir=\"ltr\">function formatMoney(cents, symbol = &quot;$&quot;) { … }</code> استُدعيت هكذا: <code dir=\"ltr\">formatMoney(450, undefined)</code>. ما قيمة <code dir=\"ltr\">symbol</code> داخلها؟</p>","options":[{"text":"<code dir=\"ltr\">undefined</code>، لأنك مرّرتها صراحةً.","why":"القيم الافتراضية تُطبَّق على الوسائط المفقودة وعلى الوسائط التي قيمتها <code dir=\"ltr\">undefined</code>، سواء مُرّرت أم لا."},{"text":"<code dir=\"ltr\">&quot;$&quot;</code>","why":"صحيح. تمرير <code dir=\"ltr\">undefined</code> يُعامَل تمامًا مثل حذف الوسيط، فتُطبَّق القيمة الافتراضية."},{"text":"<code dir=\"ltr\">null</code>","why":"لا شيء هنا يُنتج <code dir=\"ltr\">null</code>. ثم إن تمرير <code dir=\"ltr\">null</code> لا يُفعّل القيمة الافتراضية؛ وحدها <code dir=\"ltr\">undefined</code> تفعل ذلك."}],"answer":1},{"q":"<p>أيّ سطر يستدعي <code dir=\"ltr\">isBig</code> قبل تعريفها دون أن يحدث خطأ؟</p>","options":[{"text":"<code dir=\"ltr\">console.log(isBig(100)); const isBig = (c) =&gt; c &gt; 50;</code>","why":"أسماء <code dir=\"ltr\">const</code> لا يمكن استخدامها قبل أن يُنفَّذ سطرها، لذلك يرمي هذا خطأ ReferenceError."},{"text":"<code dir=\"ltr\">console.log(isBig(100)); let isBig = function (c) { return c &gt; 50; };</code>","why":"قيمة الدالة مخزّنة في <code dir=\"ltr\">let</code>، وهي غير متاحة قبل سطر التصريح بها."},{"text":"<code dir=\"ltr\">console.log(isBig(100)); function isBig(c) { return c &gt; 50; }</code>","why":"صحيح. تصريحات الدوال “تُرفع” (hoisted)، أي أن الدالة كاملة تكون متاحة من أعلى نطاقها."}],"answer":2},{"q":"<p>لديك <code dir=\"ltr\">const amounts = [450, 1220];</code> و<code dir=\"ltr\">function toDollars(c) { return c / 100; }</code>. ماذا يحتاج منك <code dir=\"ltr\">amounts.map(toDollars)</code>؟</p>","options":[{"text":"لا شيء إضافي. <code dir=\"ltr\">map</code> تستدعي <code dir=\"ltr\">toDollars</code> لكل عنصر وتجمع النتائج.","why":"صحيح. أنت تمرّر الدالة نفسها، دون أقواس، و<code dir=\"ltr\">map</code> تقرّر متى تستدعيها."},{"text":"<code dir=\"ltr\">amounts.map(toDollars())</code> مع الأقواس، كي تُنفَّذ الدالة.","why":"هذا يستدعي <code dir=\"ltr\">toDollars</code> مرة واحدة فورًا دون أي وسيط، ويمرّر ناتجها، <code dir=\"ltr\">NaN</code>، إلى <code dir=\"ltr\">map</code>، التي ترمي خطأ حينها."},{"text":"حلقة تكرار حولها، لأن <code dir=\"ltr\">map</code> لا تعمل إلا مع قيمة واحدة.","why":"<code dir=\"ltr\">map</code> تمرّ على المصفوفة كلها بنفسها. وهذا هو الهدف من تمرير دالة إليها."}],"answer":0}],"exercise":{"kind":"web","mode":"js","starter":{"js":"// 1. Dollars (like 4.1) to whole cents (410)\nfunction toCents(dollars) {\n}\n\n// 2. Cents to a display string, with a symbol that defaults to \"$\"\nfunction formatMoney(cents) {\n}\n\n// 3. Replace null with an arrow function: true for 10000 cents or more\nconst isBig = null;\n\n// 4. Count the amounts for which test(amount) returns true\nfunction countWhere(amounts, test) {\n  return 0;\n}\n\nconsole.log(formatMoney(toCents(12.2)));\n"},"solution":{"js":"function toCents(dollars) {\n  return Math.round(dollars * 100);\n}\n\nfunction formatMoney(cents, symbol = \"$\") {\n  return `${symbol}${(cents / 100).toFixed(2)}`;\n}\n\nconst isBig = (cents) => cents >= 10000;\n\nfunction countWhere(amounts, test) {\n  let count = 0;\n  for (const amount of amounts) {\n    if (test(amount)) {\n      count++;\n    }\n  }\n  return count;\n}\n\nconsole.log(formatMoney(toCents(12.2)));\n"},"checks":[{"id":"to-cents","test":"return toCents(4.1) === 410 && toCents(12.2) === 1220 && toCents(0.07) === 7;\n"},{"id":"format","test":"return formatMoney(1220) === '$12.20' && formatMoney(5) === '$0.05';\n"},{"id":"format-symbol","test":"return formatMoney(1220, '€') === '€12.20' && formatMoney(450, undefined) === '$4.50';\n"},{"id":"is-big-arrow","test":"return typeof isBig === 'function' && !('prototype' in isBig) && isBig(10000) === true && isBig(9999) === false;\n"},{"id":"count-where","test":"const amounts = [450, 12000, 99, 10000];\nreturn countWhere(amounts, isBig) === 2 && countWhere(amounts, (c) => c < 100) === 1 && countWhere([], isBig) === 0;\n"}],"title":"الدوال المساعدة للمال في Pocket","prompt":"<p>اكتب أربع دوال صغيرة سيستخدمها Pocket من الآن فصاعدًا:</p>\n<ol>\n<li><code dir=\"ltr\">toCents(dollars)</code> تُرجع المبلغ بالسنتات الصحيحة (<code dir=\"ltr\">4.1</code> تعطي <code dir=\"ltr\">410</code>).</li>\n<li><code dir=\"ltr\">formatMoney(cents, symbol)</code> تُرجع نصًا مثل <code dir=\"ltr\">&quot;$12.20&quot;</code>. والقيمة الافتراضية لـ <code dir=\"ltr\">symbol</code> هي <code dir=\"ltr\">&quot;$&quot;</code>.</li>\n<li><code dir=\"ltr\">isBig</code>، وهي <strong>دالة سهمية</strong> تُرجع <code dir=\"ltr\">true</code> لمبلغ 10000 سنت أو أكثر.</li>\n<li><code dir=\"ltr\">countWhere(amounts, test)</code> تُرجع عدد العناصر في <code dir=\"ltr\">amounts</code> التي تجعل الـ callback <code dir=\"ltr\">test(amount)</code> تُرجع قيمة truthy.</li>\n</ol>\n","hints":["تذكّر <code dir=\"ltr\">Math.round</code>، لأن <code dir=\"ltr\">4.1 * 100</code> لا تساوي 410 بالضبط. وتذكّر <code dir=\"ltr\">return</code>: دونها يعطي كل استدعاء <code dir=\"ltr\">undefined</code>.","المعامل الافتراضي يُكتب في قائمة المعاملات: <code dir=\"ltr\">function formatMoney(cents, symbol = &quot;$&quot;)</code>.","<code dir=\"ltr\">const isBig = (cents) =&gt; cents &gt;= 10000;</code> وفي <code dir=\"ltr\">countWhere</code>، استدعِ الـ callback داخل حلقة: <code dir=\"ltr\">if (test(amount)) { count++; }</code>."],"explanation":"<p>كل دالة مساعدة تُرجع نتيجتها بدلًا من طباعتها، فيستطيع المُستدعون الجمع بينها: <code dir=\"ltr\">formatMoney(toCents(12.2))</code> تُدخل القيمة المُعادة من دالة مباشرةً في الدالة التالية. والقيمة الافتراضية <code dir=\"ltr\">symbol = &quot;$&quot;</code> تُطبَّق كلما كان الوسيط مفقودًا أو <code dir=\"ltr\">undefined</code>. وتستخدم <code dir=\"ltr\">isBig</code> الصيغة القصيرة للدالة السهمية، حيث التعبير الوحيد بعد <code dir=\"ltr\">=&gt;</code> هو القيمة المُعادة. أما <code dir=\"ltr\">countWhere</code> فلا تحتاج أبدًا إلى معرفة ما يفحصه الاختبار؛ إنها تستدعي أي دالة أُعطيت لها، مرة لكل مبلغ. وتمرير <code dir=\"ltr\">isBig</code> دون أقواس يسلّم الدالة نفسها، وهكذا بالضبط تعمل دوال المصفوفات في القسم 3.</p>\n","checkLabels":{"to-cents":"<code dir=\"ltr\">toCents</code> تُرجع سنتات صحيحة","format":"<code dir=\"ltr\">formatMoney</code> تُرجع نصوصًا مثل “$12.20”","format-symbol":"<code dir=\"ltr\">formatMoney</code> تستخدم رمزًا مخصّصًا، وقيمته الافتراضية “$”","is-big-arrow":"<code dir=\"ltr\">isBig</code> دالة سهمية بحدّ 10000 سنت","count-where":"<code dir=\"ltr\">countWhere</code> تعدّ العناصر التي تجتاز الـ callback"}},"words":646,"readMinutes":4}