How to convert a value to string in JavaScript?

👨‍💻 Frontend Developer 🟡 Often Asked 🎚️ Medium
#JavaScript #JS Basics #Strings

Quick Answer

String conversion in JavaScript can be performed in several ways:

  • String() — universal constructor
  • toString() — object method
  • Template literals`${value}`
  • Concatenation"" + value
  • JSON.stringify() — for objects and arrays

All String Conversion Methods

MethodSyntaxFeaturesExample
String()String(value)Safe, works with null/undefinedString(123)"123"
toString()value.toString()Error with null/undefined(123).toString()"123"
Template literals`${value}`Modern syntax`${123}`"123"
Concatenation"" + valueShort notation"" + 123"123"
JSON.stringify()JSON.stringify(value)For complex objectsJSON.stringify({a: 1})"{\"a\":1}"

1. String() Constructor

Universal Method

// Numbers
console.log(String(123)); // "123"
console.log(String(3.14)); // "3.14"
console.log(String(-42)); // "-42"
console.log(String(Infinity)); // "Infinity"
console.log(String(NaN)); // "NaN"
 
// Boolean values
console.log(String(true)); // "true"
console.log(String(false)); // "false"
 
// null and undefined
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
 
// Objects
console.log(String({})); // "[object Object]"
console.log(String([])); // ""
console.log(String([1, 2, 3])); // "1,2,3"

String() Advantages

// Safety with null and undefined
let value = null;
console.log(String(value)); // "null" - works
// console.log(value.toString()); // TypeError!
 
// Works with all types
let values = [123, true, null, undefined, {}, []];
values.forEach(val => {
  console.log(String(val)); // Everything works
});

2. toString() Method

Basic Usage

// Numbers
console.log((123).toString()); // "123"
console.log(Number(3.14).toString()); // "3.14"
 
// Boolean values
console.log(true.toString()); // "true"
console.log(false.toString()); // "false"
 
// Arrays
console.log([1, 2, 3].toString()); // "1,2,3"
console.log([].toString()); // ""
 
// Objects
console.log({}.toString()); // "[object Object]"
console.log(new Date().toString()); // "Mon Jan 01 2024 12:00:00 GMT+0300"

toString() with Number Base

let num = 255;
 
console.log(num.toString()); // "255" (decimal)
console.log(num.toString(2)); // "11111111" (binary)
console.log(num.toString(8)); // "377" (octal)
console.log(num.toString(16)); // "ff" (hexadecimal)
console.log(num.toString(36)); // "73" (maximum base)
 
// Practical example
function toHex(num) {
  return '#' + num.toString(16).padStart(6, '0');
}
 
console.log(toHex(16711680)); // "#ff0000" (red color)

toString() Limitations

// Errors with null and undefined
try {
  console.log(null.toString()); // TypeError
} catch (e) {
  console.log('Error:', e.message);
}
 
try {
  console.log(undefined.toString()); // TypeError
} catch (e) {
  console.log('Error:', e.message);
}
 
// Safe check
function safeToString(value) {
  return value != null ? value.toString() : String(value);
}
 
console.log(safeToString(123)); // "123"
console.log(safeToString(null)); // "null"

3. Template Literals

Modern ES6+ Syntax

// Simple values
console.log(`${123}`); // "123"
console.log(`${true}`); // "true"
console.log(`${null}`); // "null"
console.log(`${undefined}`); // "undefined"
 
// In context
let name = "Alexander";
let age = 25;
console.log(`My name is ${name}, I am ${age} years old`); 
// "My name is Alexander, I am 25 years old"
 
// Calculations inside
let a = 10, b = 20;
console.log(`Sum: ${a + b}`); // "Sum: 30"
console.log(`Result: ${a > b ? 'a is greater' : 'b is greater'}`); 
// "Result: b is greater"

Multiline Templates

let user = {
  name: "Anna",
  email: "anna@example.com",
  role: "admin"
};
 
let template = `
User:
  Name: ${user.name}
  Email: ${user.email}
  Role: ${user.role}
`;
 
console.log(template);

Functions in Templates

function formatDate(date) {
  return date.toLocaleDateString('en-US');
}
 
function formatCurrency(amount) {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(amount);
}
 
let order = {
  id: 12345,
  date: new Date(),
  total: 1500.50
};
 
let receipt = `
Order #${order.id}
Date: ${formatDate(order.date)}
Total: ${formatCurrency(order.total)}
`;
 
console.log(receipt);

4. String Concatenation

Implicit Conversion

// Simple concatenation
console.log("" + 123); // "123"
console.log("" + true); // "true"
console.log("" + null); // "null"
console.log("" + undefined); // "undefined"
 
// With space
console.log(" " + 123); // " 123"
 
// Multiple concatenation
let result = "Value: " + 42 + ", status: " + true;
console.log(result); // "Value: 42, status: true"

Operator Precedence Features

// Order matters
console.log("Result: " + 5 + 3); // "Result: 53"
console.log("Result: " + (5 + 3)); // "Result: 8"
 
// Mixed operations
console.log(5 + 3 + " units"); // "8 units"
console.log("Total " + 5 + 3 + " units"); // "Total 53 units"
console.log("Total " + (5 + 3) + " units"); // "Total 8 units"

5. JSON.stringify() for Objects

Object Serialization

// Simple objects
let obj = { name: "John", age: 30 };
console.log(JSON.stringify(obj)); // '{"name":"John","age":30}'
 
// Arrays
let arr = [1, 2, 3, "test", true];
console.log(JSON.stringify(arr)); // '[1,2,3,"test",true]'
 
// Nested structures
let complex = {
  user: {
    name: "Maria",
    contacts: {
      email: "maria@example.com",
      phones: ["+1-123-456-78-90", "+1-098-765-43-21"]
    }
  },
  timestamp: new Date().toISOString()
};
 
console.log(JSON.stringify(complex, null, 2)); // Pretty formatting

JSON.stringify() Parameters

let data = {
  name: "Product",
  price: 1000,
  secret: "do not show",
  category: "electronics"
};
 
// With replacer function
let filtered = JSON.stringify(data, (key, value) => {
  return key === 'secret' ? undefined : value;
});
console.log(filtered); // Without secret field
 
// With key array
let selected = JSON.stringify(data, ['name', 'price']);
console.log(selected); // Only name and price
 
// With indentation
let formatted = JSON.stringify(data, null, 4);
console.log(formatted); // With 4-space indentation

JSON.stringify() Limitations

// Values that don't serialize
let problematic = {
  func: function() { return 42; },
  undef: undefined,
  symbol: Symbol('test'),
  date: new Date(),
  regex: /test/g,
  infinity: Infinity,
  nan: NaN
};
 
console.log(JSON.stringify(problematic));
// '{"date":"2024-01-01T12:00:00.000Z","infinity":null,"nan":null}'
 
// Circular references
let circular = { name: "test" };
circular.self = circular;
 
try {
  JSON.stringify(circular);
} catch (e) {
  console.log('Error:', e.message); // Converting circular structure to JSON
}

Method Comparison

CriteriaString()toString()TemplateConcatJSON.stringify()
Safety with null/undefined
Works with primitives
Works with objectsBasicBasicBasicBasicFull
Format customizationPartial
PerformanceHighHighMediumHighLow
Code readabilityGoodGoodExcellentMediumGood

Practical Tasks

Task 1: What will the console output?

console.log(String(0));
console.log(String(""));
console.log(String(false));
console.log(String(null));
console.log(String(undefined));
Answer

"0", "", "false", "null", "undefined"

String() converts all values to their string representation.

Task 2: Fix the error

function convertToString(value) {
  return value.toString();
}
 
console.log(convertToString(123)); // works
console.log(convertToString(null)); // error!
Answer
function convertToString(value) {
  return String(value); // or
  // return value != null ? value.toString() : String(value);
}

Use String() for safe conversion.

Task 3: Number formatting

let number = 255;
// Need to get: "Number 255 in binary: 11111111"
Answer
let number = 255;
let result = `Number ${number} in binary: ${number.toString(2)}`;
console.log(result);

Use template literals and toString() with base.

Task 4: Object serialization

let user = {
  name: "Anna",
  age: 25,
  password: "secret123",
  email: "anna@example.com"
};
 
// Need to get JSON without password field
Answer
// Method 1: replacer function
let json1 = JSON.stringify(user, (key, value) => {
  return key === 'password' ? undefined : value;
});
 
// Method 2: key array
let json2 = JSON.stringify(user, ['name', 'age', 'email']);
 
// Method 3: destructuring
let { password, ...userWithoutPassword } = user;
let json3 = JSON.stringify(userWithoutPassword);

Task 5: Concatenation optimization

// Which method is faster for multiple concatenation?
let values = [1, 2, 3, 4, 5];
 
// Option A
let resultA = "";
for (let val of values) {
  resultA += val + ", ";
}
 
// Option B
let resultB = values.join(", ");
 
// Option C
let resultC = values.map(String).join(", ");
Answer

Option B is fastest for simple values. Option C is better for complex objects. Option A is slowest due to multiple concatenations.

// Optimal solution
let result = values.join(", "); // "1, 2, 3, 4, 5"

Advanced Techniques

Custom toString() Conversion

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  toString() {
    return `User(${this.name}, ${this.age})`;
  }
  
  // For JSON.stringify()
  toJSON() {
    return {
      type: 'User',
      name: this.name,
      age: this.age,
      createdAt: new Date().toISOString()
    };
  }
}
 
let user = new User("Peter", 30);
console.log(String(user)); // "User(Peter, 30)"
console.log(JSON.stringify(user)); // Uses toJSON()

Performance and Optimization

// Benchmark different methods
function benchmark() {
  const iterations = 1000000;
  const value = 12345;
  
  console.time('String()');
  for (let i = 0; i < iterations; i++) {
    String(value);
  }
  console.timeEnd('String()');
  
  console.time('toString()');
  for (let i = 0; i < iterations; i++) {
    value.toString();
  }
  console.timeEnd('toString()');
  
  console.time('Template');
  for (let i = 0; i < iterations; i++) {
    `${value}`;
  }
  console.timeEnd('Template');
  
  console.time('Concat');
  for (let i = 0; i < iterations; i++) {
    "" + value;
  }
  console.timeEnd('Concat');
}
 
// benchmark(); // Uncomment for testing

Internationalization

// Localized conversion
function localizedString(value, locale = 'en-US') {
  if (typeof value === 'number') {
    return value.toLocaleString(locale);
  }
  
  if (value instanceof Date) {
    return value.toLocaleDateString(locale);
  }
  
  return String(value);
}
 
console.log(localizedString(1234567.89)); // "1,234,567.89"
console.log(localizedString(new Date())); // "1/1/2024"
 
// Currency formatting
function formatCurrency(amount, currency = 'USD', locale = 'en-US') {
  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency
  }).format(amount);
}
 
console.log(formatCurrency(1500.50)); // "$1,500.50"

Common Mistakes and Pitfalls

1. Errors with null and undefined

// Dangerous
function badConvert(value) {
  return value.toString(); // TypeError for null/undefined
}
 
// Safe
function safeConvert(value) {
  return String(value); // Works with all types
}
 
// Or with check
function checkedConvert(value) {
  return value != null ? value.toString() : 'empty';
}

2. Precision loss with large numbers

// Problem with large numbers
let bigNumber = 9007199254740992n; // BigInt
console.log(String(bigNumber)); // "9007199254740992"
console.log(bigNumber.toString()); // "9007199254740992"
 
// JSON.stringify doesn't work with BigInt
try {
  JSON.stringify(bigNumber);
} catch (e) {
  console.log('Error:', e.message);
}
 
// Solution
function serializeBigInt(key, value) {
  return typeof value === 'bigint' ? value.toString() : value;
}
 
let data = { id: 123n, name: "test" };
console.log(JSON.stringify(data, serializeBigInt));

3. Unexpected behavior with objects

// Objects convert unexpectedly
let obj = { name: "test", value: 42 };
console.log(String(obj)); // "[object Object]"
console.log(obj.toString()); // "[object Object]"
 
// For readable output use JSON.stringify
console.log(JSON.stringify(obj)); // '{"name":"test","value":42}'
 
// Or custom toString
obj.toString = function() {
  return `${this.name}: ${this.value}`;
};
console.log(String(obj)); // "test: 42"

4. Array problems

// Arrays convert with commas
let arr = [1, 2, 3];
console.log(String(arr)); // "1,2,3"
console.log(arr.toString()); // "1,2,3"
 
// For other separators
console.log(arr.join(' | ')); // "1 | 2 | 3"
console.log(arr.join('')); // "123"
 
// Nested arrays
let nested = [[1, 2], [3, 4]];
console.log(String(nested)); // "1,2,3,4"
console.log(JSON.stringify(nested)); // "[[1,2],[3,4]]"

Modern Features

Internationalization (Intl API)

// Number formatting
const numberFormatter = new Intl.NumberFormat('en-US', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
 
console.log(numberFormatter.format(1234.5)); // "1,234.50"
 
// Relative time
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // "yesterday"
console.log(rtf.format(2, 'hour')); // "in 2 hours"
 
// Lists
const listFormatter = new Intl.ListFormat('en', {
  style: 'long',
  type: 'conjunction'
});
 
const items = ['apples', 'bananas', 'oranges'];
console.log(listFormatter.format(items)); // "apples, bananas, and oranges"

Tagged Template Literals

// Custom tag for HTML
function html(strings, ...values) {
  return strings.reduce((result, string, i) => {
    const value = values[i] ? escapeHtml(values[i]) : '';
    return result + string + value;
  }, '');
}
 
function escapeHtml(text) {
  return String(text)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}
 
const userInput = '<script>alert("XSS")</script>';
const safeHtml = html`<div>User entered: ${userInput}</div>`;
console.log(safeHtml); // Safe HTML

Summary

String conversion in JavaScript is a fundamental operation. It’s important to understand:

String() — safest universal method
toString() — fast, but requires null/undefined check
Template literals — modern and readable syntax
JSON.stringify() — for serializing complex objects
Performance — choose method based on task

In modern development, prefer:

  • String() for safe conversion
  • Template literals for readable string building
  • JSON.stringify() for object serialization
  • Performance testing for critical code paths

Master these methods to handle string conversion confidently in any JavaScript project! 🚀