- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Выразительный JavaScript - Марейн Хавербеке
Шрифт:
Интервал:
Закладка:
if (!test)
throw new AssertionFailed(message);
}
function lastElement(array) {
assert(array.length > 0, "пустой массив в lastElement");
return array[array.length - 1];
}
Это – компактный способ ужесточения требований к значениям, который выбрасывает исключение в случае, когда заданное условие не выполняется. К примеру, функция lastElement, добывающая последний элемент массива, вернула бы undefined для пустых массивов, если бы мы не использовали assertion. Извлечение последнего элемента пустого массива не имеет смысла, и это явно было бы ошибкой программиста.
Утверждения – способ убедиться в том, что ошибки провоцируют прерывание программы в том месте, где они совершены, а не просто выдают странные величины, которые передаются по системе и вызывают проблемы в каких-то других, не связанных с этим, местах.
Итог
Ошибки и недопустимые входные данные случаются в жизни. Ошибки в программах надо искать и исправлять. Их легче найти, используя автоматические системы проверок и добавляя утверждения в ваши программы.
Проблемы, вызванные чем-то, что неподвластно вашей программе, нужно обрабатывать достойно. Иногда, когда проблему можно решить локально, допустимо возвращать специальные значения для отслеживания таких случаев. В других случаях предпочтительно использовать исключения.
Выброс исключения приводит к разматыванию стека до тех пор, пока не будет встречен блок try/catch или пока мы не дойдём до дна стека. Значение исключения будет передано в блок catch, который сможет удостовериться в том, что это исключение действительно то, которое он ждёт, и обработать его. Для работы с непредсказуемыми событиями в потоке программы можно использовать блоки finally, чтобы определённые части кода были выполнены в любом случае.
Упражнения
Повтор
Допустим, у вас есть функция primitiveMultiply, которая в 50% случаев перемножает 2 числа, а в остальных случаях выбрасывает исключение типа MultiplicatorUnitFailure. Напишите функцию, обёртывающую эту, и просто вызывающую её до тех пор, пока не будет получен успешный результат.
Убедитесь, что вы обрабатываете только нужные вам исключения.
function MultiplicatorUnitFailure() {}
function primitiveMultiply(a, b) {
if (Math.random() < 0.5)
return a * b;
else
throw new MultiplicatorUnitFailure();
}
function reliableMultiply(a, b) {
// Ваш код
}
console.log(reliableMultiply(8, 8));
// → 64
Запертая коробка
Рассмотрим такой, достаточно надуманный, объект:
var box = {
locked: true,
unlock: function() { this.locked = false; },
lock: function() { this.locked = true; },
_content: [],
get content() {
if (this.locked) throw new Error("Заперто!");
return this._content;
}
};
Это коробочка с замком. Внутри лежит массив, но до него можно добраться только, когда коробка не заперта. Напрямую обращаться к свойству _content нельзя.
Напишите функцию withBoxUnlocked, принимающую в качестве аргумента функцию, которая отпирает коробку, выполняет функцию, и затем обязательно запирает коробку снова перед выходом – неважно, выполнилась ли переданная функция правильно, или она выбросила исключение.
function withBoxUnlocked(body) {
// Ваш код
}
withBoxUnlocked(function() {
box.content.push("золотишко");
});
try {
withBoxUnlocked(function() {
throw new Error("Пираты на горизонте! Отмена!");
});
} catch (e) {
console.log("Произошла ошибка:", e);
}
console.log(box.locked);
// → true
В качестве призовой игры убедитесь, что при вызове withBoxUnlocked, когда коробка не заперта, коробка остаётся незапертой.
9. Регулярные выражения
Некоторые люди, столкнувшись с проблемой, думают: «О, а использую-ка я регулярные выражения». Теперь у них есть две проблемы.
Джейми ЗавинскиЮан-Ма сказал: «Требуется большая сила, чтобы резать дерево поперёк структуры древесины. Требуется много кода, чтобы программировать поперёк структуры проблемы.
Мастер Юан-Ма, «Книга программирования»Инструменты и техники программирования выживают и распространяются хаотично-эволюционным способом. Иногда выживают не красивые и гениальные, а просто такие, которые достаточно хорошо работают в своей области – к примеру, если их интегрируют в другую успешную технологию.
В этой главе мы обсудим такой инструмент – регулярные выражения. Это способ описывать шаблоны в строковых данных. Они создают небольшой отдельный язык, который входит в JavaScript и во множество других языков и инструментов.
Регулярки одновременно очень странные и крайне полезные. Их синтаксис загадочен, а программный интерфейс в JavaScript для них неуклюж. Но это мощный инструмент для исследования и обработки строк. Разобравшись с ними, вы станете более эффективным программистом.
Создаём регулярное выражение
Регулярка – тип объекта. Её можно создать, вызвав конструктор RegExp, или написав нужный шаблон, окружённый слэшами.
var re1 = new RegExp("abc");
var re2 = /abc/;
Оба этих регулярных выражения представляют один шаблон: символ “a”, за которым следует символ “b”, за которым следует символ “c”.
Если вы используете конструктор RegExp, тогда шаблон записывается как обычная строка, поэтому действуют все правила относительно обратных слэшей.
Вторая запись, где шаблон находится между слэшами, обрабатывает обратные слэши по-другому. Во-первых, так как шаблон заканчивается прямым слэшем, то нужно ставить обратный слэш перед прямым слэшем, который мы хотим включить в наш шаблон. Кроме того, обратные слэши, не являющиеся частью специальных символов типа n, будут сохранены (а не проигнорированы, как в строках), и изменят смысл шаблона. У некоторых символов, таких, как знак вопроса или плюс, есть особое значение в регулярках, и если вам нужно найти такой символ, его также надо предварять обратным слэшем.
var eighteenPlus = /eighteen+/;
Чтобы знать, какие символы надо предварять слэшем, вам надо выучить список всех специальных символов в регулярках. Пока это нереально, поэтому в случае сомнений просто ставьте обратный слэш перед любым символом, не являющимся буквой, числом или пробелом.
Проверяем на совпадения
У регулярок есть несколько методов. Простейший – test. Если передать ему строку, он вернёт булевское значение, сообщая, содержит ли строка вхождение заданного шаблона.
console.log(/abc/.test("abcde"));
// → true
console.log(/abc/.test("abxde"));
// → false
Регулярка, состоящая только из неспециальных символов, просто представляет собой последовательность этих символов. Если abc есть где-то в строке, которую мы проверяем (не только в начале), test вернёт true.
Ищем набор символов
Выяснить, содержит ли строка abc, можно было бы и при помощи indexOf. Регулярки позволяют пройти дальше и составлять более сложные шаблоны.
Допустим, нам надо найти любой номер. Когда мы в регулярке помещаем набор символов в квадратные скобки, это означает, что эта часть выражения совпадает с любым из символов в скобках.
Оба выражения находятся в строчках, содержащих цифру.
console.log(/[0123456789]/.test("in 1992"));
// → true
console.log(/[0-9]/.test("in 1992"));
// → true
В квадратных скобках тире между двумя символами используется для задания диапазона символов, где последовательность задаётся кодировкой Unicode. Символы от 0 до 9 находятся там просто подряд (коды с 48 до 57), поэтому [0-9] захватывает их все и совпадает с любой цифрой.
У нескольких групп символов есть свои встроенные сокращения:
d – любая цифра
w – алфавитно-цифровой символ
s – пробельный символ (пробел, табуляция, перевод строки, и т. п.)
D – не цифра
W – не алфавитно-цифровой символ
S – не пробельный символ
. – любой символ, кроме перевода строки
Таким образом можно задать формат даты и времени вроде 30-01-2003 15:20 следующим выражением:
var dateTime = /dd-dd-dddd dd:dd/;
console.log(dateTime.test("30-01-2003 15:20"));
// → true
console.log(dateTime.test("30-jan-2003 15:20"));
// → false
Выглядит ужасно, не так ли? Слишком много обратных слэшей, которые затрудняют понимание шаблона. Позже мы слегка улучшим его.