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

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

DALL·E 2024-09-06 12.34.24 - A visually engaging post about Python and cryptographic problems. The image should feature a dark-themed background with a glowing, futuristic Python
פתרונות ומאמרים על פיתוח אינטרנט

בעיות במימוש של פונקציות קריפטוגרפיות בפייתון

היום (16 לספטמבר) ממש, אני מעביר הרצאה ב-PyconIL 2024 על בעיות קריפטוגרפיות באפליקציות פייתון. לצערי אי אפשר להכניס את כל הבעיות הקריפטוגרפיות להרצאה אחת או

מיקרו בקרים

חיבור מצלמה למיקרובקר

חיבור מצלמה למיקרו בקר ויצירה של מצלמת אבטחה מרחוק בעלות של 20 שקל.

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

יישום של nonce על מנת להגן מפני התקפות injection

בפוסט הקודם הסברתי על hash עם CSP על משאבי inline – שזה נחמד ומעולה אבל פחות ישים בעולם האמיתי שבו בדרך כלל התוכן ה-inline (בין

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