أضافت المتصفّحات مؤخرًا طريقة جديدة قابلة للتشغيل التفاعلي يمكنك استخدامها مع المصفوفات:
Array.prototype.with().
تستكشف هذه المقالة طريقة عمل هذه الطريقة وكيفية استخدامها لتعديل مصفوفة بدون تغيير المصفوفة الأصلية.
مقدمة عن Array.prototype.with(index, value)
تعرض الطريقة Array.prototype.with(index, value) نسخة من الصفيف الذي تم استدعاؤه مع ضبط index على قيمة value الجديدة التي تقدّمها.
يعرض المثال التالي مصفوفة من الأعمار. تريد إنشاء نسخة جديدة من المصفوفة مع تغيير العمر الثاني من 15 إلى 16:
const ages = [10, 15, 20, 25];
const newAges = ages.with(1, 16);
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)
توضيح الرمز البرمجي:: تعرض ages.with(...) نسخة من المتغير ages
بدون تعديل المصفوفة الأصلية. يستبدل ages.with(1, …) العنصر الثاني
(index = 1). يعيّن ages.with(1, 16) العنصر الثاني إلى 16.
هذه هي الطريقة التي تمكّنت من خلالها من إنشاء نسخة جديدة من المصفوفة مع إجراء تعديل.
هذه الطريقة مفيدة جدًا عندما تريد التأكّد من أنّ المصفوفة الأصلية تظل بدون تغيير، وتتناول هذه المقالة بعض حالات الاستخدام. ولكن، في الوقت الحالي، ألقِ نظرة على ما كان سيحدث لو استخدمت صيغة الأقواس المربعة:
const ages = [10, 15, 20, 25];
const newAges = ages;
newAges[1] = 16;
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 16, 20, 25] (Also changed 🙁)
كما نلاحظ، تم تعديل المتغيّر ages أيضًا في هذا المثال. ويرجع ذلك إلى أنّه عند تعيين ages = newAges، لا تنسخ JavaScript المصفوفة، بل تنشئ مرجعًا إلى المصفوفة الأخرى. لذلك، أي تغيير في أحدهما سيؤثّر أيضًا في الآخر لأنّهما يشيران إلى المصفوفة نفسها.
Array.prototype.with() وعدم التغيير
تُعدّ عدم القابلية للتغيير من الميزات الأساسية في العديد من مكتبات وأُطر عمل الواجهة الأمامية، مثل React (وRedux) وVue.
بالإضافة إلى ذلك، لا تتطلّب المكتبات وأُطر العمل الأخرى عدم التغيير بالضرورة، ولكنها تشجّع عليه لتحسين الأداء، مثل Angular وLit.
لذلك، كان على المطوّرين غالبًا استخدام طرق أخرى تعرض نُسخًا من المصفوفات، ما أدى إلى التأثير سلبًا في سهولة قراءة الرمز البرمجي:
const ages = [10, 15, 20, 25];
const newAges = ages.map((age, index) => {
if (index === 1) {
return 16;
}
return age;
});
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (Remains unchanged)
في ما يلي مثال على Codepen يوضّح كيفية استخدام .with() في React مع useState لتعديل مجموعة من العناصر بشكل غير قابل للتغيير:
بما أنّ الطريقة .with() تعرض نسخة من المصفوفة، يمكنك ربط عدة طلبات .with() أو حتى طرق أخرى للمصفوفة. يوضّح المثال التالي كيفية زيادة العمر الثاني والثالث من المصفوفة:
const ages = [10, 15, 20, 25];
const newAges = ages.with(1, ages[1] + 1).with(2, ages[2] + 1)
console.log(newAges); // [10, 16, 21, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)
طُرق جديدة أخرى غير قابلة للتغيير
أصبحت ثلاث طرق أخرى قابلة للتشغيل التفاعلي مؤخرًا:
Array.prototype.toReversed()التي تعكس ترتيب عناصر المصفوفة بدون تغيير المصفوفة الأصلية.Array.prototype.toSorted()التي ترتّب المصفوفة بدون تغيير المصفوفة الأصلية.Array.prototype.toSpliced()التي تعمل مثل.splice()ولكن بدون تغيير المصفوفة الأصلية.
وفقًا لموقع MDN، هذه الطرق الثلاث هي نُسخ من نظيراتها، ولكنها لا تعدّل البيانات الأصلية. يمكن أيضًا استخدام هذه الطرق في الحالات التي يُتوقّع فيها أو يُفضّل فيها عدم التغيير.
في الختام، يمكن إجراء التعديلات غير القابلة للتغيير بسهولة أكبر في JavaScript باستخدام إحدى الطرق الأربع الموضّحة في هذه المقالة. على وجه التحديد، تسهّل طريقة .with() تعديل عنصر واحد في المصفوفة بدون تغيير المصفوفة الأصلية.