Template Literals and String Interpolation
Using template literals for dynamic string creation
Challenge
Section titled “Challenge”You need to create dynamic HTML strings with proper formatting, handle multi-line text, and avoid string concatenation complexity. How do you write clean, readable string templates?
Explanation
Section titled “Explanation”Template literals (backtick strings) provide string interpolation, multi-line support, and tagged template functions for advanced string processing.
Basic Template Literals
Section titled “Basic Template Literals”const name = 'Alice';const age = 30;
// ❌ String concatenationconst message1 = 'My name is ' + name + ' and I am ' + age + ' years old';
// ✅ Template literalconst message2 = `My name is ${name} and I am ${age} years old`;
// Expression evaluationconst result = `The sum is ${10 + 20}`; // 'The sum is 30'
// Function calls in templatesfunction getAge(birth) { return new Date().getFullYear() - birth;}const desc = `I was born in ${2000} and I'm ${getAge(2000)} years old`;Multi-line Strings
Section titled “Multi-line Strings”// ❌ Concatenation with \nconst html1 = '<div>' + '\n' + ' <h1>Title</h1>' + '\n' + ' <p>Content</p>' + '\n' + '</div>';
// ✅ Template literals preserve formattingconst html2 = `<div> <h1>Title</h1> <p>Content</p></div>`;
// With variablesconst title = 'Welcome';const content = 'Hello World';
const page = ` <!DOCTYPE html> <html> <body> <h1>${title}</h1> <p>${content}</p> </body> </html>`;Tagged Templates
Section titled “Tagged Templates”// Basic tag functionfunction tag(strings, ...values) { console.log(strings); // Array of string parts console.log(values); // Array of expression values
let result = ''; strings.forEach((str, i) => { result += str; if (i < values.length) { result += values[i].toString().toUpperCase(); } }); return result;}
const name = 'alice';const result = tag`Hello ${name}, welcome!`;// Logs: ['Hello ', ', welcome!'], ['alice']// Returns: 'Hello ALICE, welcome!'
// Practical: HTML escapingfunction html(strings, ...values) { const escape = (str) => { return String(str) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); };
let result = ''; strings.forEach((str, i) => { result += str; if (i < values.length) { result += escape(values[i]); } }); return result;}
const userInput = '<script>alert("xss")</script>';const safe = html`<div>${userInput}</div>`;// Safe HTML with proper escapingAdvanced Tagged Templates
Section titled “Advanced Tagged Templates”// CSS-in-JS exampleconst colors = { primary: '#3498db', danger: '#e74c3c' };
function css(strings, ...values) { // Process CSS rules return strings.reduce((result, str, i) => { return result + str + (values[i] || ''); }, '');}
const buttonStyle = css` background-color: ${colors.primary}; padding: 10px 20px; border-radius: 4px;
&:hover { background-color: ${colors.danger}; }`;
// SQL query builderfunction sql(strings, ...values) { // Sanitize values for SQL safety const sanitized = values.map(v => { if (typeof v === 'string') { return `'${v.replace(/'/g, "''")}'`; } return v; });
let query = ''; strings.forEach((str, i) => { query += str; if (i < sanitized.length) { query += sanitized[i]; } }); return query;}
const userId = 42;const query = sql`SELECT * FROM users WHERE id = ${userId}`;// Returns: "SELECT * FROM users WHERE id = 42"Performance Considerations
Section titled “Performance Considerations”// ✅ Template literals are compiled to concatenationconst x = 'hello';const a = `${x} world`; // Compiled to x + ' world'
// Dynamic templates (slower)const userTemplate = (user) => ` <div class="user"> <h2>${user.name}</h2> <p>${user.email}</p> </div>`;
// Pre-compiled templates (faster)const template = (name, email) => ` <div class="user"> <h2>${name}</h2> <p>${email}</p> </div>`;
// For large-scale templating, consider libraries like:// - Handlebars// - EJS// - Nunjucks