{"id":"l-js-1-2","courseId":"javascript-fundamentals","lang":"ar","kind":"lesson","summary":"تتعرّف على أنواع القيم الأساسية في JavaScript، وتفحصها باستخدام typeof، وتخزّن القيم في متغيّرات باستخدام const وlet، وتختار المناسب منهما في كل مرة.","html":"<p>يحتاج Pocket إلى أن يتذكّر أشياء: اسم التطبيق، وكم أنفقت اليوم، وهل تجاوزت ميزانيتك. يتذكّر البرنامج بأن يحتفظ بـ <strong>قيم</strong> ويمنحها <strong>أسماء</strong>. وقبل أن تفعل أي شيء مثير، عليك أن تعرف أنواع القيم الموجودة وكيف تسمّيها.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">القيم وأنواعها</h2>\n<p>القيمة قطعة واحدة من البيانات. ولكل قيمة <strong>نوع بيانات</strong> (type)، وهو الذي يحدّد ما يمكنك فعله بها. هذه الأنواع الخمسة تغطّي معظم ما ستتعامل معه في أسابيعك الأولى:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"جدول قابل للتمرير\" tabindex=\"0\"><table><thead>\n<tr>\n<th>النوع</th>\n<th>أمثلة</th>\n<th>يُستخدم لـ</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>number</td>\n<td><code dir=\"ltr\">42</code>، <code dir=\"ltr\">4.5</code>، <code dir=\"ltr\">-3</code></td>\n<td>المبالغ والأعداد والقياسات</td>\n</tr>\n<tr>\n<td>string</td>\n<td><code dir=\"ltr\">&quot;Coffee&quot;</code>، <code dir=\"ltr\">'food'</code></td>\n<td>أي نص</td>\n</tr>\n<tr>\n<td>boolean</td>\n<td><code dir=\"ltr\">true</code>، <code dir=\"ltr\">false</code></td>\n<td>إجابات نعم/لا</td>\n</tr>\n<tr>\n<td>undefined</td>\n<td><code dir=\"ltr\">undefined</code></td>\n<td>“لم تُعطَ أي قيمة بعد”</td>\n</tr>\n<tr>\n<td>null</td>\n<td><code dir=\"ltr\">null</code></td>\n<td>“فارغ عن قصد”</td>\n</tr>\n</tbody>\n</table></div><p>العامل <code dir=\"ltr\">typeof</code> يخبرك بنوع أي قيمة. شغّل هذا الكود وقارن كل سطر بالجدول:</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:#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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 42</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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Coffee\"</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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> true</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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> undefined</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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> null</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>أربع إجابات تطابق الجدول. أما الأخيرة فتقول <code dir=\"ltr\">&quot;object&quot;</code>، وهذا خطأ يعود إلى عام 1995 ولا يمكن إصلاحه أبدًا لأن ملايين المواقع تعتمد عليه. حين تحتاج إلى معرفة إن كان شيء ما <code dir=\"ltr\">null</code>، قارنه بها مباشرة: <code dir=\"ltr\">value === null</code>.</p>\n<p>هناك نوعان أساسيان آخران: bigint (للأعداد الصحيحة الضخمة) وsymbol (للعلامات الفريدة)، ونادرًا ما ستحتاجهما كمبتدئ. وكل ما عدا ذلك، مثل القوائم والسجلّات، هو <strong>كائن</strong> (object)، والقسم 3 مخصّص لها بالكامل.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">تسمية القيم باستخدام const وlet</h2>\n<p><strong>المتغيّر</strong> (variable) اسم يشير إلى قيمة. تُنشئه بـ <strong>تصريح</strong> (declaration):</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\"> appName</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Pocket\"</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\"> spentToday </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:#1F2328;--shiki-dark:#E6EDF3\">spentToday </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> spentToday </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 4.5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">spentToday </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> spentToday </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 12</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\">(appName, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"spent today:\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, spentToday);</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>اقرأ السطر 4 كما يقرؤه المحرّك: أولًا يحسب الطرف الأيمن، <code dir=\"ltr\">spentToday + 4.5</code>، أي <code dir=\"ltr\">0 + 4.5</code>، فالناتج <code dir=\"ltr\">4.5</code>. ثم يوجّه الاسم <code dir=\"ltr\">spentToday</code> إلى هذه القيمة الجديدة. علامة <code dir=\"ltr\">=</code> تعني “اجعل هذا الاسم يشير إلى”، وليس “يساوي”. ولهذا تجد <code dir=\"ltr\">x = x + 1</code> منطقية في الكود مع أنها هراء في الرياضيات.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 640 210\" role=\"img\" aria-labelledby=\"l-js-1-2-t1\"><defs><marker id=\"arrow-l-js-1-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-1-2-t1\">الاسم appName يشير إلى النص Pocket ولا يمكنه التحرّك أبدًا. أما الاسم spentToday فيشير أولًا إلى 0، ثم إلى 4.5، ثم إلى 16.5، وكل إعادة إسناد تنقل السهم إلى قيمة جديدة.</title>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"30\" width=\"150\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"95\" y=\"57\" text-anchor=\"middle\">const appName</text>\n  <path class=\"d-arrow\" d=\"M170 52 L250 52\" marker-end=\"url(#arrow-l-js-1-2-1)\"/>\n  <rect class=\"d-box\" x=\"254\" y=\"30\" width=\"120\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"314\" y=\"57\" text-anchor=\"middle\">\"Pocket\"</text>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"130\" width=\"150\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"95\" y=\"157\" text-anchor=\"middle\">let spentToday</text>\n  <rect class=\"d-box\" x=\"254\" y=\"130\" width=\"80\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"294\" y=\"157\" text-anchor=\"middle\">0</text>\n  <rect class=\"d-box\" x=\"364\" y=\"130\" width=\"80\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"404\" y=\"157\" text-anchor=\"middle\">4.5</text>\n  <rect class=\"d-box-success\" x=\"474\" y=\"130\" width=\"90\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"519\" y=\"157\" text-anchor=\"middle\">16.5</text>\n  <path class=\"d-dashed\" d=\"M170 140 L254 140\"/>\n  <path class=\"d-dashed\" d=\"M170 148 Q290 110 364 140\"/>\n  <path class=\"d-arrow\" d=\"M170 162 Q340 205 474 162\" marker-end=\"url(#arrow-l-js-1-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"520\" y=\"110\" text-anchor=\"middle\">القيمة الحالية</text>\n</svg><figcaption>إعادة إسناد let تنقل الاسم إلى قيمة جديدة</figcaption></figure>\n<p><code dir=\"ltr\">const</code> تُنشئ اسمًا لا يمكن توجيهه إلى أي مكان آخر أبدًا، و<code dir=\"ltr\">let</code> تُنشئ اسمًا يمكن توجيهه. اتّبع هذه القاعدة: <strong>صرّح بـ <code dir=\"ltr\">const</code> افتراضيًا، ولا تغيّرها إلى <code dir=\"ltr\">let</code> إلا حين تكتشف أنك تحتاج إلى إعادة الإسناد.</strong> معظم الأسماء في البرامج الحقيقية لا تتغيّر أبدًا، و<code dir=\"ltr\">const</code> تخبر القارئ التالي أن بإمكانه التوقّف عن القلق بشأنها.</p>\n<p>سترى أيضًا كلمة مفتاحية ثالثة، <code dir=\"ltr\">var</code>، في الشروحات القديمة وإجابات Stack Overflow. إنها الطريقة الأصلية للتصريح بالمتغيّرات، ولها قواعد نطاق تسبّب أخطاء (سترى السبب في درس النطاق). الكود الحديث لا يستخدمها.</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>إعادة إسناد const</span></p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"2\"><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\"> 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:#1F2328;--shiki-dark:#E6EDF3\">total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</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\"> 4.5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// TypeError: Assignment to constant variable.</span></span></code></pre></div>\n<p>يتوقّف البرنامج عند هذا السطر. إن كان لا بدّ أن تتغيّر القيمة فعلًا، فصرّح بها باستخدام <code dir=\"ltr\">let</code>. وإن كنت تقصد الاحتفاظ بالقيمة القديمة وصنع قيمة جديدة، فامنح الجديدة اسمًا خاصًا بها: <code dir=\"ltr\">const newTotal = total + 4.5;</code>.</p>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">النوع للقيمة، لا للمتغيّر</h2>\n<p>في JavaScript لا يملك المتغيّر نوعًا خاصًا به. إنه يشير إلى قيمة، والقيمة هي التي لها نوع. لذلك يمكن لمتغيّر <code dir=\"ltr\">let</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\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> note </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 12</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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> note);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">note </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"twelve 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\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> note);</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>تُسمّى هذه المرونة <strong>الكتابة الديناميكية للأنواع</strong> (dynamic typing). إنها مريحة، وهي أيضًا بداية كثير من أخطاء المبتدئين: يتحوّل رقم إلى نص بصمت، فيصبح مجموعك <code dir=\"ltr\">&quot;1212&quot;</code>. يُريك الدرسان التاليان متى يحدث ذلك بالضبط.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">الأسماء: القواعد والعادات</h2>\n<p>القواعد: يمكن أن يحتوي الاسم على حروف وأرقام و<code dir=\"ltr\">_</code> و<code dir=\"ltr\">$</code>، ولا يجوز أن يبدأ برقم، ولا أن يكون كلمة محجوزة مثل <code dir=\"ltr\">const</code> أو <code dir=\"ltr\">if</code>. والأسماء حسّاسة لحالة الأحرف، فـ <code dir=\"ltr\">total</code> و<code dir=\"ltr\">Total</code> متغيّران مختلفان.</p>\n<p>أما العادات التي يتّبعها كل مشروع JavaScript: اكتب الأسماء بأسلوب <strong>camelCase</strong> (<code dir=\"ltr\">spentToday</code>، <code dir=\"ltr\">monthlyBudget</code>)، واجعلها تقول ما تعنيه القيمة، لا ما نوعها. <code dir=\"ltr\">spentToday</code> أفضل من <code dir=\"ltr\">num1</code>، و<code dir=\"ltr\">isOverBudget</code> أفضل من <code dir=\"ltr\">flag</code>. وأسماء القيم المنطقية (booleans) تبدأ عادةً بـ <code dir=\"ltr\">is</code> أو <code dir=\"ltr\">has</code> أو <code dir=\"ltr\">can</code>.</p>\n<p>خطآن ستقابلهما أثناء التدرّب:</p>\n<ul>\n<li><code dir=\"ltr\">ReferenceError: spent is not defined</code> يعني أنك استخدمت اسمًا لم يُصرَّح به قط، وغالبًا بسبب خطأ إملائي.</li>\n<li><code dir=\"ltr\">ReferenceError: Cannot access 'spent' before initialization</code> يعني أنك استخدمت متغيّر <code dir=\"ltr\">let</code> أو <code dir=\"ltr\">const</code> في سطر يسبق التصريح به. صرّح أولًا، ثم استخدم.</li>\n</ul>\n<p>في الدرس التالي تبدأ إجراء العمليات الحسابية على أرقامك، وستكتشف لماذا لا تساوي <code dir=\"ltr\">0.1 + 0.2</code> القيمة <code dir=\"ltr\">0.3</code> تمامًا.</p>\n","toc":[{"id":"sec-1","text":"القيم وأنواعها","level":2},{"id":"sec-2","text":"تسمية القيم باستخدام const وlet","level":2},{"id":"sec-3","text":"النوع للقيمة، لا للمتغيّر","level":2},{"id":"sec-4","text":"الأسماء: القواعد والعادات","level":2}],"takeaways":["لكل قيمة نوع؛ والأنواع الأساسية هي number وstring وboolean وundefined وnull، و<code dir=\"ltr\">typeof</code> تخبرك بنوع القيمة التي بين يديك.","المتغيّر اسم يشير إلى قيمة؛ النوع للقيمة، لا للمتغيّر.","صرّح بالمتغيّر باستخدام <code dir=\"ltr\">const</code> افتراضيًا، ولا تنتقل إلى <code dir=\"ltr\">let</code> إلا حين يجب أن يشير الاسم إلى قيمة أخرى لاحقًا.","إعادة إسناد قيمة لـ <code dir=\"ltr\">const</code> ترمي خطأ TypeError، واستخدام اسم قبل التصريح به يرمي خطأ ReferenceError."],"further":[{"title":"JavaScript data types and data structures (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Data_structures"},{"title":"let (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let"},{"title":"const (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const"}],"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\">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\"> 10</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</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\"> total </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 5</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:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> total, total);</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">number 10</code>","why":"السطر الثاني يحسب <code dir=\"ltr\">10 + 5</code> ويجعل <code dir=\"ltr\">total</code> يشير إلى الناتج، فتختفي القيمة القديمة 10."},{"text":"<code dir=\"ltr\">string 15</code>","why":"القيمتان رقمان ولا توجد أي علامات تنصيص، لذلك الناتج رقم وليس نصًا."},{"text":"<code dir=\"ltr\">number 15</code>","why":"صحيح. يُحسب الطرف الأيمن أولًا (10 + 5)، ثم يُوجَّه <code dir=\"ltr\">total</code> إلى 15، وهي رقم."}],"answer":2},{"q":"<p>تخزّن اسم التطبيق، <code dir=\"ltr\">&quot;Pocket&quot;</code>، وهو لا يتغيّر أبدًا، وعدد المصاريف المُدخلة حتى الآن، وهو يزداد. أيّ التصريحات أنسب؟</p>","options":[{"text":"<code dir=\"ltr\">let</code> للاثنين، كي لا تصادف أي خطأ.","why":"هذا يعمل، لكنه يُضيّع إشارة مفيدة. <code dir=\"ltr\">const</code> تخبر القارئ، والمحرّك، أن هذا الاسم لن يتحرّك أبدًا."},{"text":"<code dir=\"ltr\">const</code> لاسم التطبيق و<code dir=\"ltr\">let</code> للعدد.","why":"صحيح. الاسم ثابت، إذن <code dir=\"ltr\">const</code>؛ والعدد يُعاد إسناده كلما زاد، إذن <code dir=\"ltr\">let</code>."},{"text":"<code dir=\"ltr\">const</code> للاثنين، وغيّر العدد بكتابة <code dir=\"ltr\">count + 1</code>.","why":"كتابة <code dir=\"ltr\">count + 1</code> وحدها تحسب رقمًا جديدًا لكنها لا تخزّنه في أي مكان. وتخزينه يحتاج إلى إعادة إسناد، وهو ما تمنعه <code dir=\"ltr\">const</code>."},{"text":"<code dir=\"ltr\">var</code> للاثنين، لأنها تعمل في كل المتصفّحات.","why":"<code dir=\"ltr\">let</code> و<code dir=\"ltr\">const</code> تعملان في كل المتصفّحات منذ سنوات. أما <code dir=\"ltr\">var</code> فلها قواعد نطاق مربكة، ويتجنّبها الكود الحديث."}],"answer":1},{"q":"<p>ماذا تُرجع <code dir=\"ltr\">typeof null</code>؟</p>","options":[{"text":"<code dir=\"ltr\">&quot;null&quot;</code>","why":"هذا منطقي، لكنه ليس ما تفعله JavaScript. الإجابة الحقيقية خطأ تاريخي أُبقي عليه حفاظًا على التوافق."},{"text":"<code dir=\"ltr\">&quot;undefined&quot;</code>","why":"<code dir=\"ltr\">undefined</code> و<code dir=\"ltr\">null</code> قيمتان مختلفتان، ولكل منهما نتيجة مختلفة مع <code dir=\"ltr\">typeof</code>."},{"text":"<code dir=\"ltr\">&quot;object&quot;</code>","why":"صحيح. إنه خطأ من الإصدار الأول لـ JavaScript، ولا يمكن إصلاحه دون أن تتعطّل مواقع قديمة. لتفحص null، اكتب <code dir=\"ltr\">value === null</code>."}],"answer":2},{"q":"<p>أيّ سطر يرمي الخطأ <code dir=\"ltr\">TypeError: Assignment to constant variable.</code>؟</p>","options":[{"text":"<code dir=\"ltr\">const rate = 5; rate = 6;</code>","why":"صحيح. <code dir=\"ltr\">const</code> تُنشئ اسمًا لا يمكن توجيهه إلى قيمة أخرى أبدًا، لذلك تفشل التعليمة الثانية."},{"text":"<code dir=\"ltr\">let rate = 5; rate = 6;</code>","why":"<code dir=\"ltr\">let</code> موجودة تحديدًا كي تستطيع إعادة الإسناد. هذا الكود يعمل بلا مشاكل وتنتهي قيمة <code dir=\"ltr\">rate</code> إلى 6."},{"text":"<code dir=\"ltr\">const rate = 5; const next = rate + 1;</code>","why":"هذا يقرأ <code dir=\"ltr\">rate</code> دون أن يغيّره، ويخزّن الناتج في اسم جديد. لا توجد أي إعادة إسناد."}],"answer":0}],"exercise":{"kind":"web","mode":"js","starter":{"js":"const appName = \"Pocket\";\nconst monthlyBudget = 2000;\n\n// 1. Declare spent, starting at 0\n// 2. Add an expense of 45 to spent, then one of 120\n// 3. Declare remaining: the budget minus what was spent\n// 4. Log the type of remaining\n"},"solution":{"js":"const appName = \"Pocket\";\nconst monthlyBudget = 2000;\n\nlet spent = 0;\nspent = spent + 45;\nspent = spent + 120;\n\nconst remaining = monthlyBudget - spent;\nconsole.log(typeof remaining);\n"},"checks":[{"id":"spent-total","test":"return typeof spent === 'number' && spent === 165;"},{"id":"remaining-value","test":"return remaining === 1835;"},{"id":"logs-type","test":"return logs.some((l) => l.trim() === 'number');"},{"id":"budget-const","test":"try { monthlyBudget = 1; return false; } catch (e) { return e instanceof TypeError; }\n"}],"title":"تتبّع ما أنفقته","prompt":"<p>لدى Pocket ميزانية شهرية <code dir=\"ltr\">monthlyBudget</code> قدرها 2000. صرّح بمتغيّر <code dir=\"ltr\">spent</code> يبدأ من <code dir=\"ltr\">0</code>، ثم أعِد إسناده مرتين لتضيف مصروفًا قدره <code dir=\"ltr\">45</code> وآخر قدره <code dir=\"ltr\">120</code>. صرّح بـ <code dir=\"ltr\">remaining</code> على أنه <code dir=\"ltr\">monthlyBudget</code> ناقص <code dir=\"ltr\">spent</code>، واطبع <strong>نوع</strong> <code dir=\"ltr\">remaining</code>. أبقِ <code dir=\"ltr\">monthlyBudget</code> مُصرَّحًا به بـ <code dir=\"ltr\">const</code>.</p>\n","hints":["<code dir=\"ltr\">spent</code> يجب أن يتغيّر، لذلك لا يمكن أن يكون <code dir=\"ltr\">const</code>.","لتضيف إلى متغيّر، احسب القيمة الجديدة من القديمة: <code dir=\"ltr\">spent = spent + 45;</code>.","<code dir=\"ltr\">typeof</code> توضع قبل القيمة: <code dir=\"ltr\">console.log(typeof remaining);</code>."],"explanation":"<p>صُرّح بـ <code dir=\"ltr\">spent</code> باستخدام <code dir=\"ltr\">let</code> لأنه يُوجَّه إلى رقم جديد مرتين: <code dir=\"ltr\">0</code>، ثم <code dir=\"ltr\">45</code>، ثم <code dir=\"ltr\">165</code>. وفي كل مرة يُحسب الطرف الأيمن باستخدام القيمة الحالية قبل أن ينتقل الاسم. أما <code dir=\"ltr\">remaining</code> فلا يتغيّر بعد حسابه، لذلك <code dir=\"ltr\">const</code> هي الخيار الصحيح، و<code dir=\"ltr\">typeof remaining</code> تساوي <code dir=\"ltr\">&quot;number&quot;</code> لأن طرح رقمين يعطي رقمًا. ومحاولة إعادة إسناد <code dir=\"ltr\">monthlyBudget</code> ترمي <code dir=\"ltr\">TypeError</code>، وهذه بالضبط الحماية التي وُجدت <code dir=\"ltr\">const</code> من أجلها.</p>\n","checkLabels":{"spent-total":"قيمة <code dir=\"ltr\">spent</code> تنتهي إلى 165","remaining-value":"قيمة <code dir=\"ltr\">remaining</code> هي 1835","logs-type":"تطبع نوع <code dir=\"ltr\">remaining</code> (number)","budget-const":"<code dir=\"ltr\">monthlyBudget</code> ما زال <code dir=\"ltr\">const</code> لا يمكن إعادة إسناده"}},"words":591,"readMinutes":3}