Введение: Почему "true" не равно true?
Представьте ситуацию: вы пишете фронтенд для интернет-магазина. Пользователь выбирает опцию «Получать уведомления по email», и ваш код сохраняет её в localStorage как строку "true". При следующем визите вы читаете эту строку и пытаетесь проверить условие:
let userPref = localStorage.getItem('notifications');
if (userPref) {
// Включить уведомления
}
И тут сюрприз — условие всегда срабатывает! Даже если в localStorage лежит строка "false", JavaScript считает её truthy (истинным) значением. Не потому, что вы сделали что-то не так, а потому что любая непустая строка в JS — это true.
Эта проблема настолько популярна, что вопрос на Stack Overflow собрал тысячи просмотров и десятки вариантов решений. Сегодня мы раз и навсегда разберемся, как правильно конвертировать строку в boolean в JavaScript, рассмотрим 5 рабочих способов и выявим лучший из них.
Почему нельзя просто использовать if()?
Давайте сразу закроем этот вопрос. Многие новички думают: «Если я напишу if(str), то строка "false" превратится в false». Это опасное заблуждение.
В JavaScript есть понятие falsy (ложных) значений. Их всего 6:
false0(ноль)""(пустая строка)nullundefinedNaN
Всё остальное — truthy. Строка "false" — не пустая, в ней 5 символов. Значит, она truthy. Тоже самое с "0", "null" и даже "undefined". Простое приведение через if() или Boolean() не сработает для строк.
Топ-5 способов преобразовать строку в boolean
Мы протестировали все популярные методы из дискуссий на Stack Overflow и реальных проектов. Вот они, от худшего к лучшему.
Способ 1: Тернарный оператор (самый очевидный, но громоздкий)
function stringToBoolean(str) {
return str === 'true' ? true : str === 'false' ? false : null;
}
console.log(stringToBoolean('true')); // true
console.log(stringToBoolean('false')); // false
console.log(stringToBoolean('yes')); // null
Плюс: Понятно новичкам.
Минус: Код разрастается, если нужно обработать "yes", "1", "on". Придется писать цепочку условий.
Способ 2: JSON.parse() (элегантный, но строгий)
function stringToBoolean(str) {
try {
return JSON.parse(str);
} catch (e) {
return null;
}
}
console.log(stringToBoolean('true')); // true
console.log(stringToBoolean('false')); // false
console.log(stringToBoolean('TRUE')); // Ошибка! Вернет null
Метод JSON.parse() умеет парсить строки "true" и "false" в булевы значения. Но есть нюанс: он чувствителен к регистру. "True" или "TRUE" вызовут ошибку. Зато JSON.parse("null") вернет null, а не false — это может быть полезно.
Способ 3: Регулярное выражение (гибкий, но медленный)
function stringToBoolean(str) {
if (typeof str !== 'string') return null;
return /^(true|yes|1|on)$/i.test(str.trim());
}
console.log(stringToBoolean('true')); // true
console.log(stringToBoolean('YES')); // true
console.log(stringToBoolean('off')); // false
console.log(stringToBoolean('0')); // false
Здесь мы используем флаг i (регистронезависимость) и обрабатываем несколько вариантов «правды»: true, yes, 1, on. Всё остальное — false. Идеально для форм и пользовательского ввода.
Способ 4: Двойное отрицание !! (коротко, но опасно)
console.log(!!'true'); // true
console.log(!!'false'); // true — ВНИМАНИЕ!
console.log(!!''); // false
Оператор !! — это двойное логическое НЕ. Он превращает любое значение в его булев эквивалент. Но, как мы уже знаем, "false" — это непустая строка, поэтому !!"false" вернет true. Этот способ не решает нашу задачу.
Способ 5: Сравнение с эталоном (рекомендуемый)
function stringToBoolean(str) {
if (typeof str !== 'string') return false;
return str.toLowerCase().trim() === 'true';
}
console.log(stringToBoolean('true')); // true
console.log(stringToBoolean('FALSE')); // false
console.log(stringToBoolean(' true ')); // true (пробелы удалены)
console.log(stringToBoolean('1')); // false
Почему это лучший вариант?
- Безопасность: Функция проверяет тип аргумента. Если передать число или объект — не упадёт.
- Гибкость: Удаляем пробелы и приводим к нижнему регистру. Пользователь мог случайно нажать пробел.
- Предсказуемость: Только строка
"true"(в любом регистре) дастtrue. Всё остальное —false. - Производительность: Нет регулярок, нет JSON.parse, нет try-catch. Работает максимально быстро.
Какой способ выбрать для реального проекта?
Всё зависит от контекста. Мы подготовили шпаргалку:
| Ситуация | Рекомендуемый способ |
|---|---|
Парсинг API-ответа (строго "true"/"false") |
JSON.parse() |
Пользовательский ввод из формы ("yes", "on", "1") |
Регулярное выражение |
| Надёжное преобразование для бизнес-логики | Сравнение с эталоном (Способ 5) |