Как преобразовать значение в строку в JavaScript?

👨‍💻 Frontend Developer 📊 Средний 🎚️ Средний
#JavaScript #База JS

Краткий ответ

Преобразование в строку в JavaScript можно выполнить несколькими способами:

  • String() — универсальный конструктор
  • toString() — метод объектов
  • Шаблонные строки`${value}`
  • Конкатенация"" + value
  • JSON.stringify() — для объектов и массивов

Все способы преобразования в строку

МетодСинтаксисОсобенностиПример
String()String(value)Безопасный, работает с null/undefinedString(123)"123"
toString()value.toString()Ошибка с null/undefined(123).toString()"123"
Шаблонные строки`${value}`Современный синтаксис`${123}`"123"
Конкатенация"" + valueКраткая запись"" + 123"123"
JSON.stringify()JSON.stringify(value)Для сложных объектовJSON.stringify({a: 1})"{\"a\":1}"

1. Конструктор String()

Универсальный способ

// Числа
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"
 
// Булевы значения
console.log(String(true)); // "true"
console.log(String(false)); // "false"
 
// null и undefined
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
 
// Объекты
console.log(String({})); // "[object Object]"
console.log(String([])); // ""
console.log(String([1, 2, 3])); // "1,2,3"

Преимущества String()

// Безопасность с null и undefined
let value = null;
console.log(String(value)); // "null" - работает
// console.log(value.toString()); // TypeError!
 
// Работает со всеми типами
let values = [123, true, null, undefined, {}, []];
values.forEach(val => {
  console.log(String(val)); // Все работает
});

2. Метод toString()

Базовое использование

// Числа
console.log((123).toString()); // "123"
console.log(Number(3.14).toString()); // "3.14"
 
// Булевы значения
console.log(true.toString()); // "true"
console.log(false.toString()); // "false"
 
// Массивы
console.log([1, 2, 3].toString()); // "1,2,3"
console.log([].toString()); // ""
 
// Объекты
console.log({}.toString()); // "[object Object]"
console.log(new Date().toString()); // "Mon Jan 01 2024 12:00:00 GMT+0300"

toString() с основанием системы счисления

let num = 255;
 
console.log(num.toString()); // "255" (десятичная)
console.log(num.toString(2)); // "11111111" (двоичная)
console.log(num.toString(8)); // "377" (восьмеричная)
console.log(num.toString(16)); // "ff" (шестнадцатеричная)
console.log(num.toString(36)); // "73" (максимальное основание)
 
// Практический пример
function toHex(num) {
  return '#' + num.toString(16).padStart(6, '0');
}
 
console.log(toHex(16711680)); // "#ff0000" (красный цвет)

Ограничения toString()

// Ошибки с null и undefined
try {
  console.log(null.toString()); // TypeError
} catch (e) {
  console.log('Ошибка:', e.message);
}
 
try {
  console.log(undefined.toString()); // TypeError
} catch (e) {
  console.log('Ошибка:', e.message);
}
 
// Безопасная проверка
function safeToString(value) {
  return value != null ? value.toString() : String(value);
}
 
console.log(safeToString(123)); // "123"
console.log(safeToString(null)); // "null"

3. Шаблонные строки (Template Literals)

Современный синтаксис ES6+

// Простые значения
console.log(`${123}`); // "123"
console.log(`${true}`); // "true"
console.log(`${null}`); // "null"
console.log(`${undefined}`); // "undefined"
 
// В контексте
let name = "Александр";
let age = 25;
console.log(`Меня зовут ${name}, мне ${age} лет`); 
// "Меня зовут Александр, мне 25 лет"
 
// Вычисления внутри
let a = 10, b = 20;
console.log(`Сумма: ${a + b}`); // "Сумма: 30"
console.log(`Результат: ${a > b ? 'a больше' : 'b больше'}`); 
// "Результат: b больше"

Многострочные шаблоны

let user = {
  name: "Анна",
  email: "anna@example.com",
  role: "admin"
};
 
let template = `
Пользователь:
  Имя: ${user.name}
  Email: ${user.email}
  Роль: ${user.role}
`;
 
console.log(template);

Функции в шаблонах

function formatDate(date) {
  return date.toLocaleDateString('ru-RU');
}
 
function formatCurrency(amount) {
  return new Intl.NumberFormat('ru-RU', {
    style: 'currency',
    currency: 'RUB'
  }).format(amount);
}
 
let order = {
  id: 12345,
  date: new Date(),
  total: 1500.50
};
 
let receipt = `
Заказ №${order.id}
Дата: ${formatDate(order.date)}
Сумма: ${formatCurrency(order.total)}
`;
 
console.log(receipt);

4. Конкатенация со строкой

Неявное преобразование

// Простая конкатенация
console.log("" + 123); // "123"
console.log("" + true); // "true"
console.log("" + null); // "null"
console.log("" + undefined); // "undefined"
 
// С пробелом
console.log(" " + 123); // " 123"
 
// Множественная конкатенация
let result = "Значение: " + 42 + ", статус: " + true;
console.log(result); // "Значение: 42, статус: true"

Особенности приоритета операторов

// Порядок имеет значение
console.log("Результат: " + 5 + 3); // "Результат: 53"
console.log("Результат: " + (5 + 3)); // "Результат: 8"
 
// Смешанные операции
console.log(5 + 3 + " единиц"); // "8 единиц"
console.log("Всего " + 5 + 3 + " единиц"); // "Всего 53 единиц"
console.log("Всего " + (5 + 3) + " единиц"); // "Всего 8 единиц"

5. JSON.stringify() для объектов

Сериализация объектов

// Простые объекты
let obj = { name: "Иван", age: 30 };
console.log(JSON.stringify(obj)); // '{"name":"Иван","age":30}'
 
// Массивы
let arr = [1, 2, 3, "test", true];
console.log(JSON.stringify(arr)); // '[1,2,3,"test",true]'
 
// Вложенные структуры
let complex = {
  user: {
    name: "Мария",
    contacts: {
      email: "maria@example.com",
      phones: ["+7-123-456-78-90", "+7-098-765-43-21"]
    }
  },
  timestamp: new Date().toISOString()
};
 
console.log(JSON.stringify(complex, null, 2)); // Красивое форматирование

Параметры JSON.stringify()

let data = {
  name: "Продукт",
  price: 1000,
  secret: "не показывать",
  category: "электроника"
};
 
// С replacer функцией
let filtered = JSON.stringify(data, (key, value) => {
  return key === 'secret' ? undefined : value;
});
console.log(filtered); // Без поля secret
 
// С массивом ключей
let selected = JSON.stringify(data, ['name', 'price']);
console.log(selected); // Только name и price
 
// С отступами
let formatted = JSON.stringify(data, null, 4);
console.log(formatted); // С отступами в 4 пробела

Ограничения JSON.stringify()

// Значения, которые не сериализуются
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}'
 
// Циклические ссылки
let circular = { name: "test" };
circular.self = circular;
 
try {
  JSON.stringify(circular);
} catch (e) {
  console.log('Ошибка:', e.message); // Converting circular structure to JSON
}

Сравнение методов

КритерийString()toString()TemplateConcatJSON.stringify()
Безопасность с null/undefined
Работа с примитивами
Работа с объектамиБазоваяБазоваяБазоваяБазоваяПолная
Настройка форматаЧастично
ПроизводительностьВысокаяВысокаяСредняяВысокаяНизкая
Читаемость кодаХорошаяХорошаяОтличнаяСредняяХорошая

Практические задачи

Задача 1: Что выведет консоль?

console.log(String(0));
console.log(String(""));
console.log(String(false));
console.log(String(null));
console.log(String(undefined));
Ответ

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

String() преобразует все значения в их строковое представление.

Задача 2: Исправьте ошибку

function convertToString(value) {
  return value.toString();
}
 
console.log(convertToString(123)); // работает
console.log(convertToString(null)); // ошибка!
Ответ
function convertToString(value) {
  return String(value); // или
  // return value != null ? value.toString() : String(value);
}

Используйте String() для безопасного преобразования.

Задача 3: Форматирование числа

let number = 255;
// Нужно получить: "Число 255 в двоичной системе: 11111111"
Ответ
let number = 255;
let result = `Число ${number} в двоичной системе: ${number.toString(2)}`;
console.log(result);

Используйте шаблонные строки и toString() с основанием.

Задача 4: Сериализация объекта

let user = {
  name: "Анна",
  age: 25,
  password: "secret123",
  email: "anna@example.com"
};
 
// Нужно получить JSON без поля password
Ответ
// Способ 1: replacer функция
let json1 = JSON.stringify(user, (key, value) => {
  return key === 'password' ? undefined : value;
});
 
// Способ 2: массив ключей
let json2 = JSON.stringify(user, ['name', 'age', 'email']);
 
// Способ 3: деструктуризация
let { password, ...userWithoutPassword } = user;
let json3 = JSON.stringify(userWithoutPassword);

Задача 5: Оптимизация конкатенации

// Какой способ быстрее для множественной конкатенации?
let values = [1, 2, 3, 4, 5];
 
// Вариант A
let resultA = "";
for (let val of values) {
  resultA += val + ", ";
}
 
// Вариант B
let resultB = values.join(", ");
 
// Вариант C
let resultC = values.map(String).join(", ");
Ответ

Вариант B самый быстрый для простых значений. Вариант C лучше для сложных объектов. Вариант A самый медленный из-за множественных конкатенаций.

// Оптимальное решение
let result = values.join(", "); // "1, 2, 3, 4, 5"

Продвинутые техники

Кастомное преобразование toString()

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  toString() {
    return `User(${this.name}, ${this.age})`;
  }
  
  // Для JSON.stringify()
  toJSON() {
    return {
      type: 'User',
      name: this.name,
      age: this.age,
      createdAt: new Date().toISOString()
    };
  }
}
 
let user = new User("Петр", 30);
console.log(String(user)); // "User(Петр, 30)"
console.log(JSON.stringify(user)); // Использует toJSON()

Производительность и оптимизация

// Бенчмарк разных методов
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(); // Раскомментируйте для тестирования

Интернационализация

// Локализованное преобразование
function localizedString(value, locale = 'ru-RU') {
  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())); // "01.01.2024"
 
// Форматирование валют
function formatCurrency(amount, currency = 'RUB', locale = 'ru-RU') {
  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency
  }).format(amount);
}
 
console.log(formatCurrency(1500.50)); // "1 500,50 ₽"

Частые ошибки и подводные камни

1. Ошибки с null и undefined

// Опасно
function badConvert(value) {
  return value.toString(); // TypeError для null/undefined
}
 
// Безопасно
function safeConvert(value) {
  return String(value); // Работает со всеми типами
}
 
// Или с проверкой
function checkedConvert(value) {
  return value != null ? value.toString() : 'empty';
}

2. Потеря точности с большими числами

// Проблема с большими числами
let bigNumber = 9007199254740992n; // BigInt
console.log(String(bigNumber)); // "9007199254740992"
console.log(bigNumber.toString()); // "9007199254740992"
 
// JSON.stringify не работает с BigInt
try {
  JSON.stringify(bigNumber);
} catch (e) {
  console.log('Ошибка:', e.message);
}
 
// Решение
function serializeBigInt(key, value) {
  return typeof value === 'bigint' ? value.toString() : value;
}
 
let data = { id: 123n, name: "test" };
console.log(JSON.stringify(data, serializeBigInt));

3. Неожиданное поведение с объектами

// Объекты преобразуются не так, как ожидается
let obj = { name: "test", value: 42 };
console.log(String(obj)); // "[object Object]"
console.log(obj.toString()); // "[object Object]"
 
// Для читаемого вывода используйте JSON.stringify
console.log(JSON.stringify(obj)); // '{"name":"test","value":42}'
 
// Или кастомный toString
obj.toString = function() {
  return `${this.name}: ${this.value}`;
};
console.log(String(obj)); // "test: 42"

4. Проблемы с массивами

// Массивы преобразуются через запятую
let arr = [1, 2, 3];
console.log(String(arr)); // "1,2,3"
console.log(arr.toString()); // "1,2,3"
 
// Для других разделителей
console.log(arr.join(' | ')); // "1 | 2 | 3"
console.log(arr.join('')); // "123"
 
// Вложенные массивы
let nested = [[1, 2], [3, 4]];
console.log(String(nested)); // "1,2,3,4"
console.log(JSON.stringify(nested)); // "[[1,2],[3,4]]"

Современные возможности

Интернационализация (Intl API)

// Форматирование чисел
const numberFormatter = new Intl.NumberFormat('ru-RU', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
 
console.log(numberFormatter.format(1234.5)); // "1 234,50"
 
// Относительное время
const rtf = new Intl.RelativeTimeFormat('ru', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // "вчера"
console.log(rtf.format(2, 'hour')); // "через 2 часа"
 
// Списки
const listFormatter = new Intl.ListFormat('ru', {
  style: 'long',
  type: 'conjunction'
});
 
const items = ['яблоки', 'бананы', 'апельсины'];
console.log(listFormatter.format(items)); // "яблоки, бананы и апельсины"

Шаблонные строки с тегами

// Кастомный тег для 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>Пользователь ввел: ${userInput}</div>`;
console.log(safeHtml); // Безопасный HTML

Резюме

Преобразование в строку в JavaScript — это фундаментальная операция. Важно понимать:

String() — самый безопасный универсальный метод
toString() — быстрый, но требует проверки на null/undefined
Шаблонные строки — современный и читаемый синтаксис
JSON.stringify() — для сериализации сложных объектов
Производительность — выбирайте метод в зависимости от задачи

В современной разработке предпочитайте:

  • String() для безопасного преобразования
  • Шаблонные строки для форматирования
  • JSON.stringify() для сериализации
  • Intl API для локализации

Хочешь больше статей по подготовке к собеседованию? Подпишись на EasyAdvice(@AleksandrEmolov_EasyAdvice), добавляй сайт в избранное и прокачивай себя каждый день 💪