עדכוני מערך לא משתנים עם Array.prototype.with

לאחרונה נוספה לדפדפן שיטה חדשה ליכולת פעולה הדדית, שאפשר להפעיל בה מערכים: Array.prototype.with().

תמיכה בדפדפן

  • 110
  • 110
  • 115
  • ‏16

מקור

המאמר הזה מסביר איך השיטה הזו עובדת ואיך להשתמש בה כדי לעדכן מערך בלי לשנות את המערך המקורי.

מבוא ל-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). הפריט השני מוקצה ל-16 על ידי ages.with(1, 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() ויכולת שינוי

התכונה 'Immutability' נמצאת בליבה של הרבה ספריות ותבניות frameworks, בין היתר: 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 כדי לעדכן מערך של פריטים בלי לשנות:

מכיוון שה-method .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)

שיטות חדשות נוספות שלא ניתנות לשינוי

יש שלוש שיטות נוספות שהתאפשרו לאחרונה לפעול בצורה הדדית:

על פי MDN, שלוש השיטות האלה הן גרסת ההעתקה של המקבילות שלהן. אפשר להשתמש בשיטות האלה גם במקרים שבהם צפויה או העדפה ואי-שינוי.

לסיכום, אפשר להשיג עדכונים שלא משתנים בקלות רבה יותר ב-JavaScript באמצעות אחת מארבע השיטות שמוצגות במאמר הזה. באופן ספציפי, השיטה .with() מאפשרת לעדכן בקלות רכיב אחד במערך בלי לשנות את המערך המקורי.