Avatar ·

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

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

Основной способ: оператор typeof

Самый простой и часто используемый метод — оператор typeof. Он возвращает строку с типом данных. Для примитивных строк (которые вы пишете в кавычках) он работает идеально:

typeof 'hello'          // "string"
typeof "мир"            // "string"
typeof `шаблонная строка` // "string"
typeof String('текст')  // "string" (вызов без new)

Но есть нюанс: если вы создаёте строку через конструктор с ключевым словом new, то получаете объект-обёртку, а не примитив:

typeof new String('текст') // "object" — не "string"!

Почему это происходит?

В JavaScript есть два способа создания строк:

  • Примитивные строки — литералы в кавычках ('a', "b", `c`) или вызов String() без new.
  • Объекты-обёртки — через new String('...'). Обычно их никто не использует, но они существуют.

В 99% случаев вам нужно проверять именно примитивные строки, поэтому typeof — ваш выбор. Если же вы хотите учесть и объекты String, используйте комбинацию typeof и instanceof:

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

isString('привет');        // true
isString(new String('тест')); // true
isString(123);             // false

Подводные камни и лучшие практики

  • null: typeof null === 'object' — это известная ошибка языка, но она не влияет на проверку строк, так как null никогда не будет строкой.
  • undefined: typeof undefined === 'undefined' — безопасно, ошибки не будет даже для необъявленной переменной (если вы используете typeof).
  • Массивы: typeof [] === 'object' — массивы не являются строками, так что проверка пройдёт корректно.

Дополнительные методы (на случай, если нужно быть уверенным на 100%)

Можно использовать Object.prototype.toString.call() — это самый надёжный способ определить внутренний тип:

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

isStrictString('текст');       // true
isStrictString(new String('')); // true
isStrictString(123);           // false

Или проверять через конструктор String (менее надёжно, так как может быть изменён):

value.constructor === String

Рекомендация

Для подавляющего большинства реальных проектов используйте просто typeof value === 'string'. Объекты new String() встречаются крайне редко, обычно в учебных примерах или при работе с устаревшим кодом. Если вы пишете библиотеку или критичный к безопасности код — добавьте проверку на instanceof String или используйте Object.prototype.toString.

<<>>

Альтернативный подход: использование библиотечных утилит

Если вы работаете в современном проекте с фреймворком или используете популярные библиотеки, у них часто есть готовые функции для проверки типов. Это избавляет от необходимости писать свои велосипеды и учитывает все краевые случаи.

Например, в lodash есть функция _.isString():

_.isString('hello');        // true
_.isString(new String('')); // true
_.isString(123);            // false
_.isString(null);           // false

Она работает надёжно и покрывает все случаи, включая объекты-обёртки.

В TypeScript (если вы его используете) проверка упрощается до использования типа string:

function processInput(input: string) {
  // TypeScript сам гарантирует, что приходит строка
}

Также можно создать свою небольшую утилиту, если не хотите подключать целую библиотеку:

const isString = (val) => typeof val === 'string' || val instanceof String;

Главное — помните: для 99% случаев typeof достаточно. Не усложняйте код без необходимости.