{"id":"l-js-3-2","courseId":"javascript-fundamentals","lang":"ar","kind":"lesson","summary":"تمثّل السجلّات الحقيقية على شكل كائنات، وتقرأ خصائصها وتحدّثها، وتفهم أن الكائنات تُتداوَل عبر المرجع، وتنسخها وتحدّثها وتفكّكها باستخدام الـ spread والـ destructuring.","html":"<p>حتى الآن كان المصروف في Pocket مجرّد رقم. لكن المصروف الحقيقي له عدّة حقائق مترابطة: ما هو، وكم كلّف، وما فئته، ومتى كان. وحفظها في مصفوفات منفصلة (<code dir=\"ltr\">labels[2]</code> و<code dir=\"ltr\">amounts[2]</code> و<code dir=\"ltr\">categories[2]</code>) ينجح إلى أن تُرتَّب إحدى المصفوفات دون الأخرى. تحتاج إلى قيمة واحدة تحملها كلها: <strong>الكائن</strong> (object).</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">الكائنات: قيم مسمّاة مجتمعة</h2>\n<p>يُكتب الكائن بأقواس معقوفة ويحتوي على <strong>خصائص</strong> (properties)، كل منها اسم وقيمة:</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\"> expense</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\">  id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-1\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  label: </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\">  amount: </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:#1F2328;--shiki-dark:#E6EDF3\">  category: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"food\"</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\">(expense.label);       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// dot notation</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\">(expense[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"amount\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// bracket notation</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\">(expense.note);        </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// missing property: undefined</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>صيغة النقطة هي الطريقة اليومية لقراءة خاصية. والأقواس المربّعة تؤدّي المهمة نفسها، لكنها تحسب ما بداخلها، وهذا ما تحتاجه حين يكون اسم الخاصية في متغيّر: <code dir=\"ltr\">const field = &quot;category&quot;; expense[field]</code>. وقراءة خاصية غير موجودة تعطي <code dir=\"ltr\">undefined</code>، لا خطأ.</p>\n<p>يمكنك إضافة الخصائص وتغييرها وحذفها بعد إنشاء الكائن:</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\"> expense</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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:#1F2328;--shiki-dark:#E6EDF3\">expense.category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// add</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">expense.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 500</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;        </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// change</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">delete</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense.category;     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// remove</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\">(expense);</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\">(Object.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">keys</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(expense), Object.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">values</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(expense));</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>حين يكون لديك متغيّر يحمل أصلًا الاسم الذي تريده للخاصية، يمكنك كتابته مرة واحدة. <code dir=\"ltr\">{ label, amount }</code> اختصار لـ <code dir=\"ltr\">{ label: label, amount: amount }</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\"> label</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Bus\"</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\"> amount</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</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\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> expense</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { label, amount, category: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"travel\"</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\">(expense);</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p><code dir=\"ltr\">Object.keys</code> و<code dir=\"ltr\">Object.values</code> تعطيانك مصفوفتين بالأسماء والقيم، و<code dir=\"ltr\">Object.entries</code> تعطيك أزواجًا، لذلك تمرّ <code dir=\"ltr\">for (const [key, value] of Object.entries(expense))</code> على كل خاصية.</p>\n<p>صارت بيانات Pocket الآن <strong>مصفوفة من الكائنات</strong>، وهي أكثر أشكال البيانات شيوعًا في JavaScript، وكل ما تعلّمته في الدرس السابق ما زال ينطبق:</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:#0550AE;--shiki-dark:#79C0FF\"> expenses</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\">  { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-1\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, category: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-2\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Train\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, category: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"travel\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-3\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Lunch\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1350</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, category: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"food\"</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:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> food</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> e.category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"food\"</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\">(food.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> e.label));</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<h2 id=\"sec-2\" tabindex=\"-1\">المراجع: اسمان وكائن واحد</h2>\n<p>هذا أهم ما يجب أن تفهمه عن الكائنات والمصفوفات. المتغيّر لا يحمل الكائن نفسه؛ بل يحمل <strong>مرجعًا</strong> (reference) إليه، مثل العنوان. ونسخ المتغيّر ينسخ العنوان:</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:#0550AE;--shiki-dark:#79C0FF\"> original</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> alias</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> original;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">alias.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 999</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\">(original.amount);       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 999</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\">(alias </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> original);    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// true: the same object</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\">({ a: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { a: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }); </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// false: two different objects</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 660 230\" role=\"img\" aria-labelledby=\"l-js-3-2-t1\"><defs><marker id=\"arrow-l-js-3-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-3-2-t1\">الاسمان original وalias يشيران كلاهما إلى الكائن نفسه، لذلك يظهر التغيير عبر alias من خلال original. أما الاسم copy فيشير إلى كائن جديد منفصل أُنشئ بالنشر.</title>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"30\" width=\"130\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"85\" y=\"57\" text-anchor=\"middle\">original</text>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"100\" width=\"130\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"85\" y=\"127\" text-anchor=\"middle\">alias</text>\n  <rect class=\"d-box\" x=\"260\" y=\"50\" width=\"260\" height=\"70\" rx=\"12\"/>\n  <text class=\"d-code\" x=\"390\" y=\"90\" text-anchor=\"middle\">{ label: \"Coffee\", amount: 999 }</text>\n  <path class=\"d-arrow\" d=\"M150 52 L256 75\" marker-end=\"url(#arrow-l-js-3-2-1)\"/>\n  <path class=\"d-arrow\" d=\"M150 122 L256 98\" marker-end=\"url(#arrow-l-js-3-2-1)\"/>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"170\" width=\"130\" height=\"44\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"85\" y=\"197\" text-anchor=\"middle\">copy</text>\n  <rect class=\"d-box-success\" x=\"260\" y=\"160\" width=\"260\" height=\"60\" rx=\"12\"/>\n  <text class=\"d-code\" x=\"390\" y=\"195\" text-anchor=\"middle\">{ label: \"Coffee\", amount: 450 }</text>\n  <path class=\"d-arrow\" d=\"M150 192 L256 192\" marker-end=\"url(#arrow-l-js-3-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"600\" y=\"90\" text-anchor=\"middle\">كائن واحد</text>\n  <text class=\"d-label-muted\" x=\"600\" y=\"195\" text-anchor=\"middle\">كائن جديد</text>\n</svg><figcaption>الإسناد ينسخ المرجع؛ والنشر يُنشئ كائنًا جديدًا</figcaption></figure>\n<p><code dir=\"ltr\">===</code> مع الكائنات تقارن المراجع، لا المحتويات. فالكائنان اللذان يبدوان متطابقين يظلّان كائنين مختلفين.</p>\n<p>ولهذا أهمية لأن الدوال تستلم المراجع أيضًا. فإن غيّرت دالة كائنًا أُعطي لها، تغيّر كائن المُستدعي:</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\"> applyDiscount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  expense.amount </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\">(expense.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.9</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:#1F2328;--shiki-dark:#E6EDF3\"> expense;</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:#0550AE;--shiki-dark:#79C0FF\"> lunch</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Lunch\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1350</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\"> discounted</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> applyDiscount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(lunch);</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\">(discounted.amount, lunch.amount); </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// both 1215</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>تبدو الدالة كأنها تُرجع نسخة مخفّضة، لكنها أعادت كتابة الأصل أيضًا بصمت. وفي مكان آخر، صار مجموع كان يشمل <code dir=\"ltr\">lunch</code> خاطئًا، ولا شيء على الشاشة يقول لماذا. هكذا تحدث أخطاء من نوع “كل ما فعلته أنني عرضت المصاريف، فلماذا تغيّرت مبالغها؟”. والحل أن تبني كائنًا جديدًا بدلًا من تغيير الكائن الذي أُعطي لك، والنشر يجعل ذلك سهلًا.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">النشر: انسخ وحدّث دون تعديل في المكان</h2>\n<p><strong>صيغة النشر</strong> (spread)، أي النقاط الثلاث، تنسخ كل خصائص كائن (أو عناصر مصفوفة) إلى كائن جديد:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"6\"><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=\"6\" 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\"> expense</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-1\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> updated</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">...</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">expense, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">500</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\">(expense.amount, updated.amount);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> list</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [expense];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> longer</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">...</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">list, { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-2\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bus\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(list.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, longer.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre><div class=\"run-output\" data-run-output=\"6\" hidden></div></div>\n<p>في <code dir=\"ltr\">{ ...expense, amount: 500 }</code> تُنسخ الخصائص بالترتيب، و<code dir=\"ltr\">amount</code> اللاحقة تكتب فوق المنسوخة. فتحصل على كائن جديد، ويبقى الأصل دون مساس. ومع <code dir=\"ltr\">map</code>، هذه هي الطريقة المعتمدة لتغيير عنصر واحد في قائمة دون تعديل أي شيء في مكانه:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"7\"><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=\"7\" 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\"> expenses</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\">  { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-1\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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:#1F2328;--shiki-dark:#E6EDF3\">  { id: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"exp-2\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bus\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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:#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\"> fixed</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">e</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (e.id </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"exp-2\"</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ?</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">...</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">e, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">300</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> e));</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\">(fixed[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].amount, expenses[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].amount);</span></span></code></pre><div class=\"run-output\" data-run-output=\"7\" hidden></div></div>\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<p>النشر نسخة <strong>سطحية</strong> (shallow): إنه ينسخ خصائص المستوى الأعلى فقط. فإن كانت إحدى الخصائص كائنًا بحدّ ذاتها، مثل <code dir=\"ltr\">tags: [&quot;work&quot;]</code>، تشاركت النسخة والأصل تلك المصفوفة الداخلية، وإضافة عنصر إلى إحداهما تغيّر الاثنتين. وحين تحتاج إلى نسخة مستقلة تمامًا من بيانات متداخلة، استخدم <code dir=\"ltr\">structuredClone(value)</code>.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">التفكيك: فكّ الحزمة إلى متغيّرات</h2>\n<p><strong>التفكيك</strong> (destructuring) يسحب الخصائص من كائن إلى متغيّرات تحمل الأسماء نفسها:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"8\"><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=\"8\" 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\"> expense</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Train\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, category: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"travel\"</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:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">label</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">note</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"no note\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense;</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\">(label, amount, note);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">first</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">second</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 style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"travel\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"fun\"</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\">(first, second);</span></span></code></pre><div class=\"run-output\" data-run-output=\"8\" hidden></div></div>\n<p><code dir=\"ltr\">= &quot;no note&quot;</code> قيمة افتراضية، تُستخدم حين تكون الخاصية مفقودة أو <code dir=\"ltr\">undefined</code>. ومع المصفوفات، يعتمد التفكيك على الموضع بدلًا من الاسم.</p>\n<p>والتفكيك أكثر ما يكون نفعًا في معاملات الدوال، حيث يوثّق بالضبط الخصائص التي تحتاجها الدالة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"9\"><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=\"9\" 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\"> describe</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({ </span><span style=\"color:#953800;--shiki-dark:#FFA657\">label</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">category</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"other\"</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\">label</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}: $${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">amount</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\">category</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 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\">describe</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({ label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Train\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }));</span></span></code></pre><div class=\"run-output\" data-run-output=\"9\" hidden></div></div>\n<p>قارنها بالنسخة الخالية من التفكيك، التي تكرّر <code dir=\"ltr\">expense.</code> في كل سطر وتُخفي الخصائص المهمة حتى تقرأ الجسم كله. أما مع التفكيك، فالسطر الأول من الدالة هو عقدها: أعطني شيئًا فيه تسمية ومبلغ، وفئة اختيارية. ويستطيع المُستدعون تمرير كائن مصروف كامل فيه عشر خصائص أخرى؛ والدالة ببساطة تتجاهل الباقي.</p>\n<p>وتعمل <code dir=\"ltr\">...</code> أيضًا بالعكس، بصفتها <strong>rest</strong> (البقية): <code dir=\"ltr\">const { id, ...details } = expense</code> تضع <code dir=\"ltr\">id</code> في متغيّر خاص به، وكل الخصائص الأخرى في كائن جديد اسمه <code dir=\"ltr\">details</code>. وهذه طريقة أنيقة للتخلّص من خاصية دون تعديل الأصل: كل ما لم تسمّه ينتهي في الكائن الجديد.</p>\n<p>صارت لدى Pocket بيانات واقعية. وفي الدرس التالي تلخّصها: مجاميع لكل فئة، وقوائم مرتّبة حسب المبلغ.</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}],"takeaways":["الكائن يجمع قيمًا مسمّاة (خصائص)؛ اقرأها بصيغة النقطة، أو بالأقواس المربّعة حين يكون اسم الخاصية في متغيّر.","الكائنات والمصفوفات تُتداوَل عبر المرجع (reference)، لذلك يمكن أن يشير اسمان إلى الكائن نفسه، ويظهر التغيير عبر أحدهما من خلال الآخر.","النشر (<code dir=\"ltr\">{ ...expense, amount: 500 }</code> و<code dir=\"ltr\">[...list, item]</code>) يصنع نسخة جديدة سطحية، وهكذا تحدّث البيانات دون تعديلها في مكانها.","التفكيك (<code dir=\"ltr\">const { label, amount } = expense</code>) يسحب الخصائص إلى متغيّرات، ويعمل في معاملات الدوال مع القيم الافتراضية."],"further":[{"title":"Working with objects (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects"},{"title":"Destructuring (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring"},{"title":"Spread syntax (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"}],"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\"> a</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { label: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, amount: </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\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> b</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\">b.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 500</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\">(a.amount);</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">500</code>، لأن <code dir=\"ltr\">a</code> و<code dir=\"ltr\">b</code> يشيران إلى الكائن نفسه.","why":"صحيح. هناك كائن واحد فقط. وتغييره عبر <code dir=\"ltr\">b</code> يظهر من خلال <code dir=\"ltr\">a</code>."},{"text":"<code dir=\"ltr\">450</code>، لأن <code dir=\"ltr\">b</code> نسخة من <code dir=\"ltr\">a</code>.","why":"إسناد كائن إلى اسم آخر ينسخ المرجع، لا الكائن. فكلا الاسمين يشيران إلى الكائن نفسه."},{"text":"خطأ TypeError، لأن <code dir=\"ltr\">a</code> مُصرَّح به بـ <code dir=\"ltr\">const</code>.","why":"<code dir=\"ltr\">const</code> تمنع إعادة توجيه <code dir=\"ltr\">a</code>. أما تغيير خاصية في الكائن الذي يشير إليه فمسموح."}],"answer":0},{"q":"<p><code dir=\"ltr\">const updated = { ...expense, amount: 500 };</code> ما الصحيح بعد ذلك؟</p>","options":[{"text":"أصبحت <code dir=\"ltr\">expense.amount</code> تساوي 500.","why":"النشر يبني كائنًا جديدًا تمامًا، ولا يمسّ الأصل."},{"text":"<code dir=\"ltr\">updated</code> هو الكائن نفسه <code dir=\"ltr\">expense</code>.","why":"<code dir=\"ltr\">{ ... }</code> تُنشئ دائمًا كائنًا جديدًا، لذلك <code dir=\"ltr\">updated === expense</code> تساوي false."},{"text":"لدى <code dir=\"ltr\">updated</code> كل خصائص <code dir=\"ltr\">expense</code>، مع استبدال <code dir=\"ltr\">amount</code> بـ 500.","why":"صحيح. تُنسخ الخصائص بالترتيب، و<code dir=\"ltr\">amount</code> اللاحقة تكتب فوق المنسوخة."}],"answer":2},{"q":"<p>إذا كان <code dir=\"ltr\">const expense = { label: &quot;Bus&quot;, amount: 270 };</code>، فماذا يعطيك <code dir=\"ltr\">const { label, category = &quot;other&quot; } = expense;</code>؟</p>","options":[{"text":"<code dir=\"ltr\">label</code> تساوي “Bus” و<code dir=\"ltr\">category</code> تساوي “other”.","why":"صحيح. تُنسخ <code dir=\"ltr\">label</code> من الكائن، و<code dir=\"ltr\">category</code> غير موجودة فيه، فتُستخدم القيمة الافتراضية."},{"text":"<code dir=\"ltr\">label</code> تساوي “Bus” و<code dir=\"ltr\">category</code> تساوي undefined.","why":"هذا صحيح لو لم توجد القيمة الافتراضية. لكن <code dir=\"ltr\">= &quot;other&quot;</code> تُطبَّق حين تكون الخاصية مفقودة."},{"text":"يرمي خطأ، لأن <code dir=\"ltr\">category</code> ليست خاصية في <code dir=\"ltr\">expense</code>.","why":"تفكيك خاصية مفقودة لا يرمي خطأ أبدًا؛ إنه يعطي <code dir=\"ltr\">undefined</code>، أو القيمة الافتراضية إن وفّرت واحدة."}],"answer":0},{"q":"<p>لديك <code dir=\"ltr\">const key = &quot;category&quot;;</code>. كيف تقرأ <code dir=\"ltr\">expense.category</code> باستخدام <code dir=\"ltr\">key</code>؟</p>","options":[{"text":"<code dir=\"ltr\">expense.key</code>","why":"صيغة النقطة تستخدم الاسم الحرفي بعد النقطة، لذلك تبحث هذه عن خاصية اسمها “key”."},{"text":"<code dir=\"ltr\">expense[key]</code>","why":"صحيح. الأقواس المربّعة تحسب التعبير بداخلها، لذلك تقرأ <code dir=\"ltr\">expense[key]</code> الخاصية التي اسمها هو قيمة <code dir=\"ltr\">key</code>."},{"text":"<code dir=\"ltr\">expense[&quot;key&quot;]</code>","why":"علامات التنصيص تجعلها النص الحرفي “key”، تمامًا مثل <code dir=\"ltr\">expense.key</code>."}],"answer":1}],"exercise":{"kind":"web","mode":"js","starter":{"js":"const expenses = [\n  { id: \"exp-1\", label: \"Coffee\", amount: 450, category: \"food\" },\n  { id: \"exp-2\", label: \"Train\", amount: 1220, category: \"travel\" },\n];\n\n// Return a NEW array with the expense added at the end\nfunction addExpense(list, expense) {\n  list.push(expense);\n  return list;\n}\n\n// Return a NEW array where the expense with this id has the new amount\nfunction updateAmount(list, id, amount) {\n  const found = list.find((e) => e.id === id);\n  found.amount = amount;\n  return list;\n}\n\n// \"Train: $12.20 (travel)\"; category defaults to \"other\"\nfunction describe(expense) {\n  return expense.label;\n}\n\nconsole.log(describe(expenses[1]));\n"},"solution":{"js":"const expenses = [\n  { id: \"exp-1\", label: \"Coffee\", amount: 450, category: \"food\" },\n  { id: \"exp-2\", label: \"Train\", amount: 1220, category: \"travel\" },\n];\n\nfunction addExpense(list, expense) {\n  return [...list, expense];\n}\n\nfunction updateAmount(list, id, amount) {\n  return list.map((e) => (e.id === id ? { ...e, amount } : e));\n}\n\nfunction describe({ label, amount, category = \"other\" }) {\n  return `${label}: $${(amount / 100).toFixed(2)} (${category})`;\n}\n\nconsole.log(describe(expenses[1]));\n"},"checks":[{"id":"add","test":"const list = [{ id: 'a', label: 'A', amount: 1 }];\nconst item = { id: 'b', label: 'B', amount: 2 };\nconst out = addExpense(list, item);\nreturn Array.isArray(out) && out.length === 2 && out[1] === item && out[0] === list[0];\n"},{"id":"add-pure","test":"const list = [{ id: 'a', label: 'A', amount: 1 }];\nconst out = addExpense(list, { id: 'b', label: 'B', amount: 2 });\nreturn list.length === 1 && out !== list;\n"},{"id":"update","test":"const list = [{ id: 'a', label: 'A', amount: 1 }, { id: 'b', label: 'B', amount: 2 }];\nconst out = updateAmount(list, 'b', 300);\nreturn Array.isArray(out) && out.length === 2 && out[1].amount === 300 && out[1].label === 'B' && out[1].id === 'b' && out[0].amount === 1;\n"},{"id":"update-pure","test":"const list = [{ id: 'a', label: 'A', amount: 1 }, { id: 'b', label: 'B', amount: 2 }];\nconst out = updateAmount(list, 'b', 300);\nreturn list[1].amount === 2 && out !== list && out[1] !== list[1];\n"},{"id":"describe","test":"return describe({ label: 'Train', amount: 1220, category: 'travel' }) === 'Train: $12.20 (travel)' && describe({ label: 'Gift', amount: 5000 }) === 'Gift: $50.00 (other)';\n"}],"title":"حدّث المصاريف دون تعديلها في مكانها","prompt":"<p>دوال كود البداية تغيّر المصفوفات والكائنات التي تُعطى لها، فتتغيّر بيانات المُستدعي من وراء ظهره. أعِد كتابتها بحيث تُرجع قيمًا جديدة بدلًا من ذلك:</p>\n<ul>\n<li><code dir=\"ltr\">addExpense(list, expense)</code> تُرجع مصفوفة <strong>جديدة</strong> في نهايتها <code dir=\"ltr\">expense</code>.</li>\n<li><code dir=\"ltr\">updateAmount(list, id, amount)</code> تُرجع مصفوفة <strong>جديدة</strong> يكون فيها المصروف صاحب ذلك الـ <code dir=\"ltr\">id</code> كائنًا <strong>جديدًا</strong> بالمبلغ الجديد <code dir=\"ltr\">amount</code>. وتبقى المصاريف الأخرى كما هي، ولا يتغيّر أي شيء في <code dir=\"ltr\">list</code>.</li>\n<li><code dir=\"ltr\">describe(expense)</code> تُرجع نصًا مثل <code dir=\"ltr\">&quot;Train: $12.20 (travel)&quot;</code>، مستخدمةً <code dir=\"ltr\">&quot;other&quot;</code> حين لا توجد فئة. فكّك المعامل.</li>\n</ul>\n","hints":["انشر المصفوفة داخل مصفوفة جديدة: <code dir=\"ltr\">[...list, expense]</code>.","للتحديث، استخدم <code dir=\"ltr\">map</code> على القائمة وأرجع إمّا <code dir=\"ltr\">{ ...e, amount }</code> أو <code dir=\"ltr\">e</code> دون تغيير، بحسب إن كانت <code dir=\"ltr\">e.id === id</code>.","فكّك مع قيمة افتراضية في قائمة المعاملات: <code dir=\"ltr\">function describe({ label, amount, category = &quot;other&quot; })</code>."],"explanation":"<p><code dir=\"ltr\">[...list, expense]</code> تنسخ مراجع العناصر الموجودة إلى مصفوفة جديدة وتضيف عنصرًا آخر، فتحتفظ مصفوفة المُستدعي بطولها. وفي <code dir=\"ltr\">updateAmount</code>، تبني <code dir=\"ltr\">map</code> أصلًا مصفوفة جديدة؛ وللعنصر المطابق تُرجع <code dir=\"ltr\">{ ...e, amount }</code>، أي كائنًا جديدًا فيه كل خصائص <code dir=\"ltr\">e</code> والمبلغ الجديد (والاختصار <code dir=\"ltr\">amount</code> يعني <code dir=\"ltr\">amount: amount</code>). أما العناصر غير المتغيّرة فتُرجَع كما هي، وهذا آمن لأن لا شيء يعدّلها. وفي <code dir=\"ltr\">describe</code>، يوثّق التفكيك في قائمة المعاملات الخصائص الثلاث التي تحتاجها الدالة، وتغطّي القيمة الافتراضية المصاريف التي لا فئة لها.</p>\n","checkLabels":{"add":"<code dir=\"ltr\">addExpense</code> تُرجع القائمة وفي نهايتها المصروف الجديد","add-pure":"<code dir=\"ltr\">addExpense</code> تترك المصفوفة الأصلية دون تغيير","update":"<code dir=\"ltr\">updateAmount</code> تغيّر مبلغ المصروف المطابق","update-pure":"<code dir=\"ltr\">updateAmount</code> تترك المصفوفة والكائنات الأصلية دون تغيير","describe":"<code dir=\"ltr\">describe</code> تنسّق المصروف، وتجعل الفئة “other” افتراضيًا"}},"words":601,"readMinutes":4}