Как в JavaScript проверить, является ли переменная строкой?
Почему 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)
Выбирайте подходящий вариант под вашу ситуацию и не усложняйте код без необходимости.