Throw: примеры (JAVASCRIPT)
throw(expression (any)): -Оператор throw
Оператор throw в JavaScript используется для генерации исключительных ситуаций (исключений). В отличие от многих других языков, throw — это оператор, а не функция. Он может применяться в любом месте кода для прерывания нормального выполнения программы и передачи управления ближайшему блоку catch.
Использование оператора:
- При возникновении ошибок в логике программы
- Для валидации входных параметров функций
- При обработке асинхронных операций с ошибками
- Для создания пользовательских типов ошибок
Синтаксис: throw выражение;
Оператор throw может принимать любое выражение в качестве аргумента. Хотя традиционно принято бросать объекты ошибок (наследники Error), технически можно использовать любые значения: строки, числа, объекты, даже null или undefined.
Оператор не возвращает значение в обычном смысле — его выполнение прерывает текущий поток выполнения. Если исключение не перехватывается блоком catch, программа завершается с ошибкой.
Базовые примеры использования
Различные варианты применения оператора throw:
1. Бросок строки (не рекомендуется на практике)
throw "Произошла ошибка";Uncaught Произошла ошибка
2. Бросок объекта Error
throw new Error("Стандартная ошибка");Uncaught Error: Стандартная ошибка
3. Бросок специализированной ошибки
throw new TypeError("Ожидалось число");Uncaught TypeError: Ожидалось число
4. Бросок с любым значением
throw {code: 404, message: "Не найдено"};Uncaught {code: 404, message: "Не найдено"}Похожие механизмы в JavaScript
В JavaScript нет прямых альтернатив оператору throw, но есть связанные механизмы обработки ошибок:
1. Конструкция try...catch...finally
Позволяет перехватывать и обрабатывать исключения, сгенерированные через throw. Используется вместе с throw, а не вместо него.
2. Promise.reject()
Для асинхронного кода, основанного на промисах, метод Promise.reject() создает отклоненный промис, который может быть обработан через .catch(). В асинхронных функциях обычно используется throw внутри, который преобразуется в отклоненный промис.
3. Генерация событий ошибок
В браузерном JavaScript можно генерировать события ошибок через dispatchEvent, но этот подход используется для других целей и не является заменой throw.
Аналоги в других языках программирования
Python: оператор raise
raise ValueError("Некорректное значение")ValueError: Некорректное значение
Отличие: Python требует использования классов исключений, бросок произвольных значений не рекомендуется.
PHP: оператор throw
throw new Exception('Ошибка в PHP');Fatal error: Uncaught Exception: Ошибка в PHP
Сходство: синтаксис похож на JavaScript, но в PHP 8.0+ можно бросать только объекты, реализующие интерфейс Throwable.
Java: ключевое слово throw
throw new IOException("Ошибка ввода-вывода");IOException: Ошибка ввода-вывода
Отличие: Java требует объявления пробрасываемых исключений в сигнатуре метода (ключевое слово throws).
C++: оператор throw
throw std::runtime_error("Ошибка времени выполнения");terminate called after throwing an instance of 'std::runtime_error'
Особенность: в современном C++ использование исключений имеет больше ограничений и рекомендаций по сравнению с JavaScript.
Типичные ошибки
1. Неперехваченные исключения
function risky() { throw new Error("Опасно!"); }
risky(); // Исключение не перехваченоUncaught Error: Опасно!
2. Бросок без new для встроенных ошибок
throw Error("Забыл new"); // Работает, но не рекомендуетсяUncaught Error: Забыл new
3. Потеря контекста при повторном throw
try { throw new Error("Оригинал"); }
catch(e) { throw "Новая строка"; } // Теряется стек оригинальной ошибкиUncaught Новая строка
4. Бросок в асинхронном коде без обработки
setTimeout(() => { throw new Error("Асинхронная ошибка"); }, 0);Uncaught Error: Асинхронная ошибка (в консоли браузера)
Изменения в последних версиях
Спецификация ECMAScript не вносила фундаментальных изменений в работу оператора throw в последних версиях. Однако есть связанные улучшения:
- ES2015 (ES6): введены классы, что упростило создание пользовательских ошибок через наследование от
Error. - ES2019: улучшена обработка стектрейсов при цепочке исключений, свойство
causeдля указания причины ошибки. - ES2022: ошибки в статических блоках классов теперь генерируются корректно.
Пример с cause (ES2019+):
throw new Error("Внешняя ошибка", {cause: new Error("Внутренняя причина")});Расширенные примеры
1. Пользовательский класс ошибки
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
function validateUser(user) {
if (!user.name) throw new ValidationError("Имя обязательно", "name");
return true;
}
try {
validateUser({});
} catch(e) {
console.log(e.name, e.message, e.field);
}ValidationError Имя обязательно name
2. Использование в асинхронных функциях
async function fetchData(url) {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
fetchData("https://invalid.url").catch(e => console.log(e.message));HTTP 404 (или другая ошибка сети)
3. Генерация нескольких типов ошибок
function parseNumber(input) {
if (typeof input !== "string") throw new TypeError("Ожидалась строка");
const num = Number(input);
if (isNaN(num)) throw new RangeError("Нечисловое значение");
if (num < 0) throw new Error("Число должно быть положительным");
return num;
}4. Повторный throw с сохранением оригинальной ошибки
try {
JSON.parse("{invalid json");
} catch(e) {
throw new Error("Ошибка парсинга конфигурации", {cause: e});
}Uncaught Error: Ошибка парсинга конфигурации
5. Использование в генераторах
function* generator() {
try {
yield 1;
} catch(e) {
console.log("Поймано в генераторе:", e);
}
yield 2;
}
const g = generator();
g.next();
g.throw(new Error("Тестовая ошибка"));
console.log(g.next().value);Поймано в генераторе: Error: Тестовая ошибка 2