انتقل إلى محتوى الدرس
الدرس 93
دورة جافا سكريبت

معاملا النشر والتجميع Spread وRest في JavaScriptJavaScript Spread and Rest Operators

أتقن معاملي النشر والتجميع Spread وRest (...) في JavaScript: انسخ وادمج المصفوفات والكائنات، واجمع وسائط الدوال المرنة، وأنشئ نسخاً عميقة مستقلة بالدالة structuredClone().
أقسام الدرس
5
الأمثلة
3
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
6
محتوى الدرس
في هذا الدرس 5تصفّح المواضيع

توظف JavaScript الحديثة رمز النقاط الثلاث المتتالية (...) لأداء وظيفتين متعاكستين ومتكاملتين يسهل التمييز بينهما فوراً بحسب موضع كتابته:

  • معامل النشر (Spread — يفرد العناصر): يوضع داخل إنشاء المصفوفات [...arr] أو الكائنات { ...obj } أو عند استدعاء دالة مثل Math.max(...scores) لتفريغ المجموعة إلى عناصر مفردة.
  • معامل التجميع (Rest — يلمّ البقية): يوضع في نهاية معاملات تعريف الدالة function log(tag, ...items) أو في الطرف الأيسر للتفكيك const [head, ...tail] = list لجمع ما تبقى في حاوية واحدة.
مخطط دوري النقاط الثلاث: النشر Spread والتجميع Rest وحد النسخ السطحي مقابل النسخ العميق عبر structuredClone()

تذكر أن الإسناد المباشر const alias = originalArr; ينسخ مرجع الذاكرة فقط فيؤثر أي تعديل فيه على المصفوفة الأصلية! أما النشر داخل قوسين مربعين جديدين فينشئ مصفوفة خارجية مستقلة بنظافة:

  • نسخ المصفوفة: const copy = [...originalArr];
  • دمج القوائم وإدراج عناصر بأي موضع: const full = ["Start", ...partA, ...partB, "End"];
  • تمرير عناصر المصفوفة كوسائط دالة: Math.max(...prices) بديلاً أنيقاً عن الأسلوب القديم apply!
JavaScript
const core = ['HTML', 'CSS'];
const modern = [...core, 'JavaScript', 'ES6'];
core.push('Draft');
const temps = [21, 34, 29, 18];
const peak = Math.max(...temps);
document.getElementById('sp-arr-out').textContent =
  'Merged: ' + modern.join(', ') + '\n' +
  'core len: ' + core.length + ' | Peak: ' + peak;

ينسخ نشر الكائنات الخصائص القابلة للتعداد إلى كائن جديد مثل const merged = { ...defaults, ...userOptions };، والقاعدة الحاسمة هنا أن الخاصية المكتوبة أخيراً تغلب ما سبقها!

لذلك نضع دائماً الإعدادات الافتراضية ...defaults أولاً ثم تفضيلات المستخدم ...userOptions بعدها لتستبدل القيم المخصصة نظيرتها الافتراضية مع الإبقاء على بقية الخيارات:

موضع الاستخدامالصياغة البرمجيةالدور والقاعدة المنظمة
إنشاء مصفوفة[1, ...items, 9]نشر Spread — يتطلب قيمة قابلة للتكرار
إنشاء كائن{ ...defaults, ...custom }نشر Spread — المفتاح المكتوب أخيراً يغلب
رأس تعريف الدالةfunction calc(tax, ...prices)تجميع Rest — يجب أن يكون آخر معامل
طرف التفكيك الأيسرconst { password, ...safeUser } = raw;تجميع Rest — يعزل بقية الخصائص في كائن نظيف

عند تعريف دالة تقبل عدداً مرناً من الوسائط—مثل function sumScores(studentName, ...scores)—يجمع معامل التجميع ...scores كل الوسائط الإضافية داخل مصفوفة Array حقيقية كاملة المزايا (تغنيك عن الكائن القديم arguments وتعمل كذلك داخل الدوال السهمية!).

قاعدة نحوية حاسمة: يجب أن يقع عنصر التجميع ...rest في آخر موضع دائماً سواء في معاملات الدالة أو في التفكيك؛ ووضع أي معامل بعده يسبب خطأ صياغة SyntaxError فوري.

JavaScript
const calcInvoice = (unit, ...amounts) => {
  let total = 0;
  for (const n of amounts) total += n;
  return total + ' ' + unit + ' (' + amounts.length + ' items)';
};
document.getElementById('rest-out').textContent =
  calcInvoice('SAR', 120, 45, 35);

احذر من أشهر فخ يقع فيه المطورون مع [...arr] و{ ...obj }: فالنشر ينفذ نسخاً سطحياً للمستوى الأول فقط (Shallow Copy)! فإذا كان الكائن يضم بداخله كائناً فرعياً أو مصفوفة داخلية (مثل user.roles)، فإن النسخة السطحية تظل مرتبطة بنفس مرجع المصفوفة الداخلية في الذاكرة، وتعديلها يفسد الكائن الأصلي بصمت!

متى احتوى الكائن على مستويات متداخلة أو تواريخ، اعتمد الدالة القياسية المدمجة structuredClone(original) لإنشاء نسخة عميقة مستقلة بالكامل (Deep Copy) تفصل جميع المستويات الفرعية بأمان.

JavaScript
const base = { name: 'Team', tags: ['js'] };
const shallow = { ...base };
const deep = structuredClone(base);
shallow.tags.push('mutated-shallow');
deep.tags.push('isolated-deep');
document.getElementById('cln-out').textContent =
  'base.tags: ' + base.tags.join(', ') + '\n' +
  'deep.tags: ' + deep.tags.join(', ');
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

ميّزت في هذا الدرس بين معامل النشر Spread ومعامل التجميع Rest، ونسخت المصفوفات والكائنات مع فهم قاعدة غلبة المفتاح الأخير، وجمعت وسائط الدوال المرنة في مصفوفة حقيقية، وعزلت البنى المتداخلة بالنسخ العميق عبر structuredClone(). الخطوة التالية: انتقل الآن إلى درس «إدارة ملفات تعريف الارتباط Cookies في JavaScript» لقراءة وضبط صلاحية وحماية ملفات الارتباط بسمات Secure وSameSite وHttpOnly!

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Spread Syntax (...) معامل النشر Spread
يفرد عناصر المصفوفة أو خصائص الكائن داخل مصفوفة جديدة أو كائن جديد أو قائمة وسائط استدعاء دالة.
للمراجعة
02 Rest Parameter (...rest) معامل التجميع Rest
يجمع بقية وسائط الدالة أو بقية العناصر المتبقية من التفكيك داخل مصفوفة حقيقية أو كائن مستقل.
للمراجعة
03 Shallow Copy النسخ السطحي للمستوى الأول
نسخ خصائص المستوى الأول فقط مع بقاء الكائنات والمصفوفات الفرعية المتداخلة مشتركة في نفس المرجع.
للمراجعة
04 structuredClone() دالة النسخ العميق المدمجة structuredClone
دالة قياسية مدمجة تنشئ نسخة عميقة مستقلة تماماً للكائنات والمصفوفات والتواريخ المتداخلة.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات2

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 2 مفهومةأول بطاقة، أول خطوة
01 ES2018 ES2018
ECMAScript 2018
إصدار المواصفة القياسية الذي وسّع عمل النشر والتجميع ليشمل خصائص الكائنات إلى جانب المصفوفات.
للمراجعة
02 RAM RAM
Random-Access Memory
الذاكرة العشوائية التي تتشارك فيها النسخ السطحية مراجع الكائنات المتداخلة بينما تفصلها النسخ العميقة.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. أضف رقمين إضافيين لاستدعاء calcInvoice في محرر التجربة وتحقق من تحديث المجموع وعدد العناصر تلقائياً.

  2. شغّل مثال مقارنة النسخ ولاحظ كيف أثّر تعديل النسخة السطحية على الأصل بينما ظلت نسخة structuredClone معزولة تماماً.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

10أسئلة 2أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي10 أسئلة تنتظرك
01

عند تنفيذ const a = { mode: "dev", port: 3000 }; ثم const b = { ...a, mode: "prod" }; ما قيمة b.mode؟

02

أين يجب أن يوضع معامل التجميع (...items) دائماً في قائمة معاملات الدالة؟

03

لماذا أدى تعديل المصفوفة الفرعية copy.nested.push(1) إلى تغير orig.nested أيضاً بعد النسخ بـ const copy = { ...orig }؟

04

ما الدالة القياسية المدمجة في JavaScript لإنشاء نسخة عميقة مستقلة للكائنات والمصفوفات المتداخلة؟

05

كيف تمرر عناصر المصفوفة const nums = [14, 88, 32] إلى الدالة Math.max() باستخدام معامل النشر؟

06

ينتج معامل التجميع (...args) مصفوفة Array حقيقية تُرجع معها الدالة Array.isArray(args) القيمة true.

07

تستطيع الدالة structuredClone() نسخ الدوال البرمجية وعناصر DOM الحية دون إطلاق أي خطأ.

08

في الجملة const [winner, ...runnersUp] = athletes; هل يعمل ...runnersUp كمعامل نشر أم تجميع؟

09

ماذا يحدث عند تقييم التعبير [...null] داخل قوسين مربعين لمصفوفة؟

10

نشر بيانات مستخدم غير موثوقة بعد إعدادات الأمان مثل ({ ...securityConfig, ...userPayload }) قد يمكّن المهاجم من استبدال رايات الحماية.