مقارنة بين slice() و splice() في JavaScript: فهم الفروقات الجوهرية بأسلوب مبسط

دقائق القراءة: 5

غالباً ما يختلط الأمر على مطوري JavaScript بين دالتي slice() و splice() نظراً لتشابه أسمائهما، لكنهما تؤديان وظيفتين مختلفتين تماماً عند التعامل مع المصفوفات. في هذا المقال، سنقوم بتوضيح الفروقات الجوهرية بين هاتين الدالتين بأسلوب مبسط وممتع، مستخدمين تشبيهاً شهياً بـ “الكعكة” لتثبيت المعلومة في ذهنك.

الخدعة البسيطة التي قد تساعدك على تذكر الفرق هي:

S (p) lice = Slice + ( p ) => Slice + in (p) lace

هذا التذكير يشير إلى أن splice تقوم بالعمليات “في مكانها” (in place)، أي أنها تعدّل المصفوفة الأصلية مباشرة، بينما slice لا تفعل ذلك.

دالة Array.prototype.slice(): شريحة كعكة لا تنتهي!

تُستخدم دالة slice() لاستخراج جزء (شريحة) من مصفوفة موجودة. تبدأ عملية الاستخراج من start point (نقطة البداية) وتستمر حتى end point (نقطة النهاية)، مع استبعاد العنصر الموجود في end point نفسه. كما يوحي اسمها، وظيفتها هي “تقطيع” عناصر من المصفوفة.

لكن على عكس تقطيع الكعكة الحقيقية، فإن استخدام slice() على مصفوفة لا يغير المصفوفة الأصلية على الإطلاق؛ بل تُعيد مصفوفة جديدة تحتوي على العناصر المستقطعة، وتبقى المصفوفة الأصلية سليمة وغير معدلة (كأنها كعكة لا تنتهي!).

arr.slice(start, [end])

قواعد استخدام slice()

  • تُرجع دالة slice() مصفوفة جديدة، وتبقى المصفوفة الأصلية غير معدلة.
  • إذا تم حذف المعامل end، فإن نقطة النهاية تصبح نهاية المصفوفة (آخر عنصر).
  • إذا كان المعامل start قيمة سالبة، يتم عد العناصر من نهاية المصفوفة.
 const infiniteCake = [ '?' , '?' , '?' , '?' , '?' , '?' ]
 let myPieceOfCake = infiniteCake.slice( 0 , 1 ) // ['?']
 let yourDoublePieceOfCake = infiniteCake.slice( 0 , 2 ) // (2) ["?", "?"]
 console .log(infiniteCake) //['?','?','?','?','?','?']

كما ترى، المصفوفة infiniteCake بقيت غير معدلة تماماً بعد عمليات الاستقطاع.

دالة Array.prototype.splice(): قطع حقيقي وتعديل في مكانه

على النقيض تماماً، تقوم دالة splice() بإجراء عملياتها في مكانها (in place)، مما يعني أنها تعدّل المصفوفة الأصلية مباشرة. بالإضافة إلى إزالة العناصر، تُستخدم splice() أيضاً لإضافة عناصر جديدة إلى المصفوفة. يمكن اعتبار splice() هي “شريحة الكعكة” في العالم الحقيقي، حيث يتم تغيير الكعكة الأصلية.

arr.splice(start, [deleteCount, itemToInsert1, itemToInsert2, ...])

قواعد استخدام splice()

  • تُنفذ العمليات في مكانها، مما يؤدي إلى تعديل المصفوفة الأصلية.
  • تُرجع دالة splice() مصفوفة تحتوي على العناصر التي تم حذفها (إن وجدت).
  • إذا كان المعامل start قيمة سالبة، يتم عد العناصر من نهاية المصفوفة.
  • إذا تم حذف المعامل deleteCount، فسيتم إزالة جميع العناصر من start حتى نهاية المصفوفة.
  • إذا تم حذف العناصر المراد إدراجها (مثل itemToInsert1)، فسيتم فقط إزالة العناصر.
 const cake = [ '?' , '?' , '?' , '?' , '?' , '?' ];
 let myPieceOfCake = cake.splice( 0 , 1 ) // ["?"]
 console .log(cake) // (5) ["?", "?", "?", "?", "?"]
 let yourDoublePieceOfCake = cake.splice( 0 , 2 ) //(2) ["?", "?"]
 console .log(cake) //(3) ["?", "?", "?"]

هنا، نلاحظ أن المصفوفة cake تم تعديلها وتقليل حجمها بعد كل عملية splice().

أمثلة برمجية عملية

لنلقِ نظرة على بعض الأمثلة البرمجية التي توضح الفروقات بشكل أكبر:

 const myArray = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ]
 console .log(myArray.slice( 0 )) // [ 1, 2, 3, 4, 5, 6, 7 ]
 console .log(myArray.slice( 0 , 1 )) // [ 1 ]
 console .log(myArray.slice( 1 )) // [ 2, 3, 4, 5, 6, 7 ]
 console .log(myArray.slice( 5 )) // [ 6, 7 ]
 console .log(myArray.slice( -1 )) // [ 7 ]
 console .log(myArray) // [ 1, 2, 3, 4, 5, 6, 7 ]

في المثال أعلاه، نرى أن المصفوفة الأصلية myArray لم تتغير أبداً، بغض النظر عن عمليات slice() التي أجريت عليها.

 const secondArray = [ 10 , 20 , 30 , 40 , 50 ]
 console .log(secondArray.splice( 0 , 1 )) // [ 10 ] : تحذف عنصراً واحداً بدءاً من الفهرس 0
 console .log(secondArray.splice( -2 , 1 )) // [ 40 ] : تحذف عنصراً واحداً بدءاً من الفهرس (نهاية-2)
 console .log(secondArray) // [ 20, 30, 50 ]
 console .log(secondArray.splice( 0 )) // [ 20, 30, 50 ] : تحذف جميع العناصر بدءاً من الفهرس 0
 console .log(secondArray) // []
 console .log(secondArray.splice( 2 , 0 , 60 , 70 )) // [] : تحذف 0 عناصر بدءاً من الفهرس 2 (حيث لا يوجد عنصر في هذا الفهرس حالياً، سيتم الإدراج في النهاية)، ثم تُدرج 60 و 70.
 console .log(secondArray) // [60, 70]

في هذا المثال، تتغير المصفوفة secondArray بشكل جذري مع كل استدعاء لدالة splice()، حيث يتم حذف وإضافة العناصر مباشرة إلى المصفوفة الأصلية.

ملخص سريع

  • استخدم دالة splice() إذا كنت بحاجة إلى تعديل المصفوفة الأصلية (إضافة أو حذف عناصر منها مباشرة).
  • استخدم دالة slice() إذا كنت ترغب في استخراج عناصر من المصفوفة دون تعديل المصفوفة الأصلية، والحصول على مصفوفة جديدة بالنتائج.

الخلاصة التقنية

إن فهم الفروقات الدقيقة بين slice() و splice() أمر حيوي لأي مطور JavaScript، حيث يؤثر بشكل مباشر على إدارة البيانات وتجنب الأخطاء غير المتوقعة. تكمن القوة الحقيقية في اختيار الأداة المناسبة للمهمة: slice() للعمليات غير المدمرة التي تحافظ على سلامة البيانات الأصلية، و splice() للعمليات المدمرة التي تتطلب تعديلاً مباشراً على بنية المصفوفة. هذا التمييز لا يعزز فقط كفاءة الكود، بل يسهم أيضاً في كتابة شيفرة أكثر وضوحاً وقابلية للصيانة، مما يقلل من التعقيد ويحسن الأداء العام للتطبيق.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *