Avatar ·

Как в JavaScript проверить, является ли переменная строкой?

Всем привет! Я новичок в JavaScript и столкнулся с проблемой. У меня есть функция, которая должна работать только со строковыми значениями. Если передать число или объект, всё ломается. Я пытаюсь проверить тип переменной с помощью typeof, но результаты меня смущают. Вот пример моего кода: ```javascript function processInput(input) { if (typeof input === 'string') { console.log('Это строка, длина: ' + input.length); } else { console.log('Это не строка!'); } } processInput('Привет'); // Работает: "Это строка, длина: 6" processInput(42); // Работает: "Это не строка!" processInput(new String('Тест')); // Выводит "Это не строка!" — а я ожидал, что это строка! processInput(null); // Выводит "Это не строка!" — ок processInput(undefined); // Выводит "Это не строка!" — ок ``` Проблема в том, что когда я создаю строку через конструктор new String(), typeof возвращает 'object', а не 'string'. Как правильно проверять, является ли переменная строкой, чтобы учитывать и обычные строки, и объекты String? Может быть, есть какой-то универсальный способ? Заранее спасибо за помощь! <<>>

Почему typeof new String('...') возвращает 'object'?

В JavaScript существует два типа строковых значений:

  • Примитивные строки — создаются литералами ('текст' или "текст") или вызовом String() без new. typeof для них возвращает 'string'.
  • Объекты-обёртки String — создаются через new String('...'). typeof для них возвращает 'object', так как это полноценный объект.

Хотя на практике вы редко будете использовать new String(), но в некоторых библиотеках или легаси-коде такое встречается. Поэтому важно уметь обрабатывать оба случая.

Лучший способ: комбинация typeof и instanceof

Самый надёжный и лаконичный способ — проверить, является ли значение строкой в любом виде:

function isString(value) {
  return typeof value === 'string' || value instanceof String;
}

Разберём по частям:

  • typeof value === 'string' — ловит все примитивные строки.
  • value instanceof String — ловит объекты String (и только их).

Пример работы:

console.log(isString('Привет'));          // true
console.log(isString(new String('Тест'))); // true
console.log(isString(42));                 // false
console.log(isString(null));               // false
console.log(isString(undefined));          // false
console.log(isString({}));                 // false
console.log(isString([]));                 // false

Альтернативный способ: Object.prototype.toString.call()

Можно использовать универсальный метод определения внутреннего типа:

function isString(value) {
  return Object.prototype.toString.call(value) === '[object String]';
}

Этот способ работает для любых значений, включая null и undefined (они вернут false). Он чуть медленнее, но абсолютно надёжен.

Что ещё стоит знать?

  • Не используйте value instanceof String без проверки на typeof — для примитивных строк instanceof вернёт false, потому что примитивы не являются экземплярами String.
  • Проверка typeof value === 'string' подходит для 99% случаев — если вы контролируете код и гарантируете, что строки создаются только литералами, этого достаточно.
  • Объекты String ведут себя как примитивы — их можно складывать, вызывать методы, но при сравнении == они преобразуются в примитив. Однако === будет возвращать false.

Итоговое решение для вашей функции

Перепишем ваш код с надёжной проверкой:

function processInput(input) {
  if (typeof input === 'string' || input instanceof String) {
    console.log('Это строка, длина: ' + input.length);
  } else {
    console.log('Это не строка!');
  }
}

processInput('Привет');              // "Это строка, длина: 6"
processInput(new String('Тест'));    // "Это строка, длина: 4"
processInput(42);                    // "Это не строка!"

Теперь ваша функция корректно обрабатывает оба типа строковых значений.

<<>>

Дополнительный подход: использование Lodash

Если вы используете популярную библиотеку Lodash, в ней уже есть готовая функция _.isString():

const _ = require('lodash');
// или import _ from 'lodash';

console.log(_.isString('Привет'));          // true
console.log(_.isString(new String('Тест'))); // true
console.log(_.isString(42));                 // false

Внутри Lodash использует комбинацию typeof и Object.prototype.toString, поэтому функция абсолютно надёжна. Это хороший вариант, если вы уже используете Lodash в проекте — не нужно писать велосипед.

Когда не стоит заморачиваться

В современных кодовых базах (ES6+) почти никто не использует new String(). Если вы пишете новый код и уверены, что строки будут только примитивными, достаточно простой проверки:

function isString(value) {
  return typeof value === 'string';
}

Это самый быстрый и читаемый вариант. Дополнительные проверки на instanceof нужны только если вы работаете с легаси-кодом или библиотеками, которые могут создавать объекты-обёртки.

Краткое резюме

  • Для 99% случаев: typeof value === 'string'
  • Для максимальной надёжности: typeof value === 'string' || value instanceof String
  • Если используете Lodash: _.isString(value)

Выбирайте подходящий вариант под вашу ситуацию и не усложняйте код без необходимости.