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

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

תמיכה בדפדפן

  • Chrome: 110.
  • קצה: 110.
  • Firefox: 115.
  • Safari: 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). 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() ואובייקטים שאינם ניתנים לשינוי

יכולת פעולה בלתי מוגבלת נמצאת בליבה של ספריות ומסגרות חזיתיות רבות, כמה: תגובה (ו-חזרה) ו-Vue

בנוסף, ספריות ומסגרות אחרות לא מחייבות בהכרח יכולת שינוי, כדי לשפר את הביצועים: Angular ו-Lite

לכן, מפתחים נאלצו לעיתים קרובות להשתמש בשיטות אחרות שהחזירו עותקים של מערכים דבר שהפחית את הקריאוּת של הקוד:

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() מאפשרת לעדכן בקלות רכיב יחיד של המערך בלי לשנות את המערך המקורי.