ES2018 – תיקונים ב Tagged template literals

התקן של ES2018 כולל תיקונים ב-Tagged template literals שהוא פיצ'ר שלא הרבה מכירים וזו ההזדמנות ללמוד עליו

הפיצ'ר הראשון שנכנס לתקן ES2018 הוא שיפור פיצ'ר אדיר שנקרא Tagged template literals והוא מרחיב את הטמפלייטינג שכבר דיברנו עליו ב-ES6. לא יצא לי להתרכז בפיצ'ר הזה בעבר אז התיקון שנכנס ל- Tagged template literals הוא הזדמנות מעולה לדבר על הפיצ'ר הזה.

אז הנה תזכורת קטנה על טמפלייטינג – באמצעות התו ` שזה גרש עקום, אני יכול לעשות טמפלייטינג וליצור טקסט עם משתנים. למשל:


const name = "Moshe";
const age = 40;
const text = `${name} is ${age} years old`;
console.log(text); // "Moshe is 40 years old"

מה הבעיה? נניח ואני רוצה לכתוב גם חוות דעת על הגיל. למשל, אם האדם מתחת לגיל 40, לכתוב:

Moshe is 39 years old and young

או לחלופין, אם הוא בן 40 ומעלה:

Moshe is 39 years old and he is dead in hightech.

איך אני עושה את זה? אני יכול לעשות משהו כזה:


const name = 'Moshe';
const age = 40;
let remark = 'and young!'
if ( age >= 40) {
  remark = 'and he is dead in hightech!'
}
const text = `${name} is ${age} years old ${remark}`;
console.log(text); // "Moshe is 40 years old and he is dead in hightech!"

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


function myTemplate(strings, var1, var2) {
  let remark = ' and young!'
  if ( var2 >= 40) {
    remark = ' and he is dead in hightech!'
  }
  return strings[0] + var1 + strings[1] + var2 + strings[2] + remark; 
}

const name = 'Moshe';
const age = 40;

const text = myTemplate`Mr ${name} is ${age} years old`;
console.log(text); // // "Mr Moshe is 40 years old and young!"

והנה דוגמה חיה שאפשר לשחק איתה:

See the Pen Tagged template literals by Ran Bar-Zik (@barzik) on CodePen.

מבלבל? שימו לב. הפונקציה היא פונקציה רגילה שמקבלת כמה פרמטרים. הפרמטר הראשון הוא מערך של כל הטקסט שהוא לא משתנה. הפרמטר השני הוא המשתנה הראשון, הפרמטר השלישי הוא המשתנה השני וכך הלאה.

תמונה להמחשה: כך המשתנים מתמיינים מהטמפלייט לפונקציה
תמונה להמחשה: כך המשתנים מתמיינים מהטמפלייט לפונקציה

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

הקריאה לפונקצית טמפלייט היא פשוטה – אני רק מציב את השם שלה (בלי סוגריים) לפני הטמפלייט.

בואו ונעשה עוד דוגמה 🙂


function mySecondTemplate(strings, var1) {
  let remark = '';
  if (var1 > 3) {
    remark = ' This is a lot!'
  }
  return strings[0] + var1 + strings[1] + remark; 
}

const number = 4;

const text = mySecondTemplate`I have ${number} childrens.`;
console.log(text); //  have 4 childrens This is a lot!"
document.write(text);

See the Pen Tagged template literals 2nd example by Ran Bar-Zik (@barzik) on CodePen.

גם פה בתוך פונקצית הטמפלייטינג אני יכול לעשות מה שבא לי בגדול. אני יכול אפילו לא להשתמש בכלל במשתנים! אפשר לקחת את זה מאוד רחוק. עכשיו, זו לא איזו פונקציונליות מטורפת שלא ראינו קודם – אבל זה כן עוזר לנו לרכז את כל מה שקשור לטמפלייטינג במקום אחד ולא ללכלך את הקוד הפונקציונלי שלנו. הפרדה בין חלקים שונים של הקוד זה חשוב ונחמד.

אז מה השיפור שיש לנו ב-ES2018? בואו וניקח את הקוד הבא:


function mySecondTemplate(strings, var1) {
  let remark = '';
  if (var1 > 3) {
    remark = ' This is a lot!'
  }
  return strings[0] + var1 + strings[1] + remark; 
}

const number = 4;

const text = mySecondTemplate`In my \c folder I have ${number} directories.`;
console.log(text); // "In my c folder I have 4 directories. This is a lot!"
document.write(text);



יעבוד, בטח שיעבוד, עכשיו בואו נשנה את זה ל u\:


function mySecondTemplate(strings, var1) {
  let remark = '';
  if (var1 > 3) {
    remark = ' This is a lot!'
  }
  return strings[0] + var1 + strings[1] + remark; 
}

const number = 4;

const text = mySecondTemplate`In my \u folder I have ${number} directories.`;
console.log(text); // NaN directories. This is a lot!
document.write(text);



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


function tag(strs) {
  strs[0] === undefined
  strs.raw[0] === "\\unicode";
}
tag`\unicode`

באמצעות raw אני יכול לגשת לערך המקורי. ואם זה נראה לכם מיותר, סימן שלא כתבתם קוד ב-node שבו השתמשתם בסלאשים כדי לעשות פעולות שונות.

אבל אתם יודעים מה? אם הבנתם רק את Tagged template literals אז זה גם סבבה 🙂

פוסטים נוספים שכדאי לקרוא

מיקרו בקרים

בית חכם עם ESPHome ו Home Assistant

הסבר על הום אסיסטנט, מערכת הקוד הפתוח לבית חכם ואיך לחבר אליה מיקרובקרים.

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

ESP32 מאפס לילדים

מדריך ל-ESP32 לילדים ולהורים מאפס

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

גלילה לראש העמוד