• בלוג
  • אופרטור שלוש נקודות של ES6: החבר הטוב ביותר החדש שלי

אופרטור שלוש נקודות של ES6: החבר הטוב ביותר החדש שלי

פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
 

כשפגשתי את אופרטור השלוש נקודות (... או בשמו המלא Spread) לראשונה לא ממש הבנתי מה רוצים ממני ולמה הוא טוב. אבל לקח בסך הכל 2-3 דוגמאות להתאהב, ואני מקוה שעד סוף הפוסט גם אתם תרגישו אותו הדבר.

1. הבעיה שבא לפתור

האופרטור בא לפתור שתי בעיות מעצבנות במיוחד ב ES5: הראשונה היא העבודה עם arguments ביצירת פונקציה המקבלת מספר משתנה של פרמטרים, והשניה היא פריסה של מערך לאיבריו לצורך העברה לפונקציה כזו.

הפוקנציה push למשל מקבלת מספר משתנה של פרמטרים. הקוד הבא עובד כמו שאתם חושבים:

const arr = [10, 20, 30];
arr.push(40, 50);

console.log(arr);
// prints [10, 20, 30, 40, 50]

אבל מה אם יש לכם כבר את האיברים כמערך? ב ES5 כתבנו קוד שנראה בערך כך:

var arr = [10, 20, 30];
var addition = [40, 50];

arr.push.apply(arr, addition);

עובד, אבל מציק. שם המערך מופיע פעמיים ומי שלא מכיר את apply עלול ללכת לאיבוד.

גרוע יותר המצב של arguments. הפונקציה הבאה ב ES5 מחשבת את סכום המספרים שהועברו אליה:

function sum() {
    var result = 0;
    for (var i=0; i < arguments.length; i++) {
        result += arguments[i];
    }
    return result;
}

אבל ES6 הוסיפה למערך את reduce, ואיפשרה לנו לחשב סכום של מערך באופן הבא:

const arr = [10, 20, 30, 40];
const sum = arr.reduce((a, b) => a+b);

הבעיה שבתוך פונקציה לא ניתן להשתמש ב map, reduce, filter או כל פונקצית מערך אחרת על arguments מאחר ואינם מערך. וכך נולדה המפלצת הבאה:

function sumWithReduce() {
    const arr = Array.prototype.slice.call(arguments);
    return arr.reduce((a,b) => a+b);
}

אופרטור spread יעזור לנו לכתוב קוד נקי יותר לשני המקרים.

2. פריסה של מערך

כתיבת ... לפני שם מערך בעת שימוש במערך (למשל לצורך העברה לפונקציה) פורסת אותו לאיבריו ומעבירה את האיברים כפרמטרים נפרדים. כך הקוד הבא עובד מעולה ומוסיף את האיברים הנוספים למערך arr:

const arr = [10, 20, 30];
const addition = [40, 50];

arr.push(...addition);

ובאותו האופן קל לממש את concat תוך שימוש ב ... בלבד:

const a1 = [10, 20, 30];
const a2 = [40, 50];

const together = [...a1, ...a2];

במערך together נקבל את כל אברי a1 ולאחריהם את כל אברי a2.

3. מימוש פונקציה המקבלת מספר משתנה של פרמטרים

ומה לגבי פונקציות המקבלות מספר משתנה של פרמטרים? אין שום בעיה. בעת הגדרת פונקציה הוספת ... לפני שם פרמטר אומר ל JavaScript שיש לאסוף חזרה איברים פרוסים למערך יחיד ולכן הפרמטר מתקבל כמערך. במלים אחרות הקוד הבא עובד:

function sumWithReduce(...args) {
    // now args is a normal array
    return args.reduce((a,b) => a+b);
}

הסיבה המרכזית שאני מעדיף את Spread Operator על פני שימוש בפונקציות כמו slice או concat זה שמאוד ברור כשרואים את השלוש נקודות שמדובר בהעתקה ופריסה של מערך, בניגוד להפעלת פונקציה שם צריך להזכר האם זו פונקציה שמשנה את המערך המקורי (לדוגמא push) או מחזירה עותק (לדוגמא slice או concat).

אופרטור Spread זמין ועובד בדפדפנים שלכם מלבד IE, Android Browser ו Node לפני גירסא 6. אפשר להמירו באופן אוטומטי לקוד ES5 שקול באמצעות Babel.