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 אז זה גם סבבה 🙂

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

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

נגישות טכנית – פודקאסט ומבוא

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

צילום מסך של סוואגר
יסודות בתכנות

openAPI

שימוש בתשתית הפופולרית למיפוי ותיעוד של API וגם הסבר בסיסי על מה זה API

בינה מלאכותית

להריץ ממשק של open-webui על הרספברי פיי

להפעיל ממשק של צ׳אט ג׳יפיטי שאפשר לגשת אליו מכל מחשב ברשת הביתית על רספברי פיי עם מודל בשם tinydolphin שרץ על רספברי פיי.

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