Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание
- Название:JavaScript. Подробное руководство, 6-е издание
- Автор:
- Жанр:
- Издательство:Символ-Плюс
- Год:2012
- Город:СПб
- ISBN:978-5-93286-215-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание краткое содержание
Эта книга - одновременно и руководство программиста, и полноценный справочник по базовому языку JavaScript и клиентским прикладным интерфейсам, предоставляемым веб-броузерами.
JavaScript. Подробное руководство, 6-е издание - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Пример 11.1. Конвейер генераторов
// Генератор, возвращающий строки текста по одной.
// Обратите внимание, что здесь не используется метод s.split(), потому что
// он обрабатывает текст целиком, создает массив, тогда как нам необходимо
// реализовать отложенную обработку,
function eachline(s) {
let р;
while((p = s.indexOf( \n')) != -1) {
yield s. substrings, p);
s = s.substring(p+1);
}
if (s.length > 0) yield s;
}
// Функция-генератор, возвращающая f(x) для каждого элемента х итерируемого объекта і
function map(і. f) {
fоr(let x in i) yield f(x);
}
// Функция-генератор, возвращающая элементы і, для которых f(x) возвращает true
function select(i, f) {
for(let x in i) {
if (f(x)) yield x;
}
}
// Обрабатываемый текст
let text = " «comment \n \n hello \nworld\n quit \n unreached \n";
// Сконструировать конвейер генераторов для обработки текста.
// Сначала разбить текст на строки
let lines = eachline(text);
// Затем удалить начальные и конечные пробелы в каждой строке
let trimmed = map(lines, function(line) { return line.trim(); });
// Наконец, игнорировать пустые строки и комментарии
let nonblank = select(trimmed, function(line) {
return line.length > 0 && 1ine[0] !=
});
// Теперь извлечь отфильтрованные строки из конвейера и обработать их,
// остановиться, если встретится строка “quit",
for (let line in nonblank) {
if (line === "quit") break; console.log(line);
}
Обычно инициализация генераторов выполняется при их создании: аргументы, передаваемые функции-генератору, являются единственными значениями, которые принимают генераторы. Однако имеется возможность передать дополнительные данные уже работающему генератору. Каждый генератор имеет метод send(),
который перезапускает генератор подобно методу next().
Разница лишь в том, что методу send()
можно передать значение, которое станет значением, возвращаемым выражением yield
в функции-генераторе. (В большинстве генераторов, которые не принимают дополнительных входных данных, ключевое слово yield
выглядит как инструкция. Однако в действительности yield
- это выражение, возвращающее значение.) Кроме методов next()
и send()
существует еще один способ перезапустить генератор - метод throw().
Если вызвать этот метод, выражение yield
возбудит аргумент метода throw()
как исключение, как показано в следующем примере:
// Функция-генератор, ведущая счет от заданного начального значения.
// Метод send() позволяет увеличить счетчик на определенное значение.
// Вызов throw("reset") сбрасывает счетчик в начальное значение.
// Это всего лишь пример - здесь метод throw() используется не самым лучшим образом,
function counter(initial) {
let nextValue = initial; // Сохранить начальное значение
while(true) {
try {
let increment = yield nextValue; // Вернуть значение и получить приращение
if (increment) // Если передано приращение...
nextValue += increment; // ...использовать его.
else nextValue++; // Иначе увеличить на 1
}
catch (e) { // Если был вызван метод
if (e==="reset") // throw() генератора
nextValue = initial; else throw e;
}
}
}
let c = counter(10); // Создать генератор с начальным значением 10
console.log(c.next()); //Выведет 10
console.log(c.send(2)); // Выведет 12
console.log(c.throw("reset")); // Выведет 10
11.4.4. Генераторы массивов
Еще одна особенность, заимствованная в JavaScript 1.7 из языка Python, - генераторы массивов. Это механизм инициализации элементов массива на основе элементов другого массива или итерируемого объекта. Синтаксис генераторов массивов основан на математической форме записи элементов множества, т. е. выражения и инструкции находятся совсем не там, где привыкли их видеть программисты на языке JavaScript. Тем не менее привыкание к необычному синтаксису происходит достаточно быстро, а мощь генераторов массивов просто неоценима.
Ниже приводится пример генератора массивов, использующего созданную выше функцию range() для инициализации массива, содержащего квадраты четных чисел, меньшие 100:
let evensquares = [х*х for (х in range(0,10)) if (х % 2 === 0)]
Эта строка примерно эквивалентна следующим пяти строкам:
let evensquares = [];
for(x in range(0,10)) {
if (x % 2 === 0)
evensquares.push(x*x);
}
В общем случае синтаксис генераторов массивов имеет следующий вид:
[ выражение for ( переменная in объект ) if ( условное выражение ) ]
Обратите внимание на три основные части в квадратных скобках:
• Цикл for/in
или for/each
без тела. Эта часть генератора массивов включает переменную (или несколько переменных при использовании присваивания с разложением) слева от ключевого слова in
и объект (который может быть генератором, итерируемым объектом или массивом) справа от ключевого слова in
. Несмотря на отсутствие тела цикла, эта часть генератора массивов выполняет итерации и присваивает последовательные значения, определяемые переменной. Обратите внимание, что перед именем переменной не допускается указывать ключевое слово var
или let
- генераторы массивов неявно используют ключевое слово let
, а используемая переменная недоступна за пределами квадратных скобок и не затирает существующую переменную с тем же именем.
• После итерируемого объекта может присутствовать ключевое слово if
и условное выражение. Если оно присутствует, условное выражение используется для фильтрации значений, по которым выполняются итерации. Условное выражение вычисляется после получения каждого значения, воспроизводимого циклом for
. Если результатом выражения является false
, это значение пропускается и в массив ничего не добавляется. Ключевое слово if
можно не указывать - если оно отсутствует, генератор массива действует так, как если бы в нем присутствовала конструкция if (true)
.
Интервал:
Закладка: