JavaScript
String Formatting
String.Format
JavaScript Tips
Web Development

Use of String.Format in JavaScript?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

JavaScript does not include a built-in String.Format method like C# by default, but it has modern alternatives that cover the same use cases. In practice, template literals, Intl APIs, and small formatter utilities solve most formatting needs with better readability. This guide shows when to use each approach and how to avoid common formatting mistakes.

Use Template Literals for Most Cases

Template literals are usually the cleanest replacement for String.Format style placeholders.

javascript
1const user = "Maya";
2const count = 3;
3const msg = `Hello ${user}, you have ${count} new messages.`;
4console.log(msg);

This style is easy to read, supports multiline strings, and handles expression interpolation directly.

javascript
1const subtotal = 59.9;
2const tax = 8.2;
3const total = subtotal + tax;
4
5const receipt = `Subtotal: ${subtotal}\nTax: ${tax}\nTotal: ${total}`;
6console.log(receipt);

Build a Lightweight Placeholder Formatter

If you prefer indexed placeholders like "Hello 0", write a utility function. This is helpful when migrating code from languages that use positional formatting.

javascript
1function format(template, ...args) {
2  return template.replace(/\{(\d+)\}/g, (match, index) => {
3    const value = args[Number(index)];
4    return value === undefined ? match : String(value);
5  });
6}
7
8console.log(format("Hello {0}, score {1}", "Ari", 98));
9console.log(format("Missing {2} stays", "x", "y"));

This utility keeps unknown placeholders unchanged, which is often safer for debugging than silently converting them to empty strings.

Use Named Placeholders for Maintainability

Indexed placeholders can get confusing with long templates. Named placeholders are easier to maintain.

javascript
1function formatNamed(template, values) {
2  return template.replace(/\{([a-zA-Z0-9_]+)\}/g, (match, key) => {
3    return Object.prototype.hasOwnProperty.call(values, key)
4      ? String(values[key])
5      : match;
6  });
7}
8
9const result = formatNamed("User {name} has role {role}", {
10  name: "Nora",
11  role: "admin"
12});
13
14console.log(result);

Named formatting reduces errors when template order changes during localization.

Locale-Aware Number and Date Formatting

For user-facing output, do not rely on raw concatenation for numbers or dates. Use Intl APIs.

javascript
1const amount = 12345.67;
2
3const currency = new Intl.NumberFormat("en-US", {
4  style: "currency",
5  currency: "USD"
6}).format(amount);
7
8const date = new Intl.DateTimeFormat("en-CA", {
9  dateStyle: "medium",
10  timeStyle: "short"
11}).format(new Date());
12
13console.log(`Amount: ${currency}`);
14console.log(`Generated: ${date}`);

This is critical for global products because separators, symbols, and date order differ by locale.

Keep Formatting Out of Business Logic

Formatting should happen near presentation boundaries. Store raw values internally and format only for logs, UI, and API responses.

javascript
1function buildInvoiceView(model, locale) {
2  const money = new Intl.NumberFormat(locale, {
3    style: "currency",
4    currency: model.currency
5  });
6
7  return {
8    id: model.id,
9    customer: model.customerName,
10    totalDisplay: money.format(model.total)
11  };
12}

This separation prevents re-parsing formatted strings later and keeps domain logic cleaner.

Formatting and Security

String formatting should not be confused with output escaping. If formatted values are rendered into HTML, still escape untrusted input or use safe templating frameworks.

javascript
1function escapeHtml(str) {
2  return str
3    .replace(/&/g, "&")
4    .replace(/</g, "&lt;")
5    .replace(/>/g, "&gt;")
6    .replace(/\"/g, "&quot;")
7    .replace(/'/g, "&#39;");
8}

Format first, then escape for the target output context.

Formatting for Localization and Plurals

Simple interpolation breaks down when messages need plural logic or locale-specific grammar. You can combine Intl.PluralRules with a small message map.

javascript
1const plural = new Intl.PluralRules("en");
2const messages = {
3  one: "You have 1 item",
4  other: (n) => `You have ${n} items`
5};
6
7function formatCount(n) {
8  const form = plural.select(n);
9  const msg = messages[form];
10  return typeof msg === "function" ? msg(n) : msg;
11}
12
13console.log(formatCount(1));
14console.log(formatCount(5));

For multi-language apps, this pattern should usually be replaced by a dedicated i18n library, but it shows why string formatting decisions affect product correctness beyond syntax.

Common Pitfalls

  • Assuming String.Format exists natively in JavaScript runtime.
  • Using positional placeholders in large templates where argument order is hard to track.
  • Formatting numbers and dates without locale-aware APIs.
  • Mixing data transformation and string formatting in one function.
  • Treating interpolation as HTML sanitization.

Summary

  • JavaScript has no native String.Format, but template literals cover most needs.
  • Custom placeholder helpers are useful for migration or legacy-style templates.
  • Prefer named placeholders for readability in larger templates.
  • Use Intl.NumberFormat and Intl.DateTimeFormat for user-facing output.
  • Keep formatting logic close to presentation and separate from core business logic.

Course illustration
Course illustration

All Rights Reserved.