JavaScript. Подробное руководство, 6-е издание, стр. 155

• После итерируемого объекта может присутствовать ключевое слово

<b>if</b>
и условное выражение. Если оно присутствует, условное выражение используется для фильтрации значений, по которым выполняются итерации. Условное выражение вычисляется после получения каждого значения, воспроизводимого циклом
<b>for</b>
. Если результатом выражения является
<b>false</b>
, это значение пропускается и в массив ничего не добавляется. Ключевое слово
<b>if</b>
можно не указывать - если оно отсутствует, генератор массива действует так, как если бы в нем присутствовала конструкция
<b>if (true)</b>
.

• Выражение, стоящее перед ключевым словом

<b>for</b>
, представляет собой эквивалент тела цикла. После того как значение, возвращаемое итератором, будет присвоено переменной и пройдет проверку условным выражением, будет вычислено значение этого выражения, и полученный результат будет добавлен в создаваемый массив.

Ниже приводятся несколько более конкретных примеров, которые помогут лучше понять синтаксис:

<b>data = [2,3,4, -5]; // Массив чисел</b>

<b>squares = [х*х for each (х in data)]; // Квадраты всех чисел: [4,9,16,25]</b>

<b>// Извлечь квадратные корни из всех неотрицательных элементов </b>

<b>roots = [Math.sqrt(x) for each (x in data) if (x &gt;= 0)]</b>

<b>// Создать массив с именами свойств объекта </b>

<b>о = {а:1, b:2, f: function(){}} </b>

<b>let allkeys = [p for (p in o)]</b>

<b>let ownkeys = [p for (p in o) if (o.hasOwnProperty(p))]</b>

<b>let notfuncs = [k for ([k,v] in Iterator(o)) if (typeof v !== &quot;function&quot;)]</b>

11.4.5. Выражения-генераторы

В JavaScript 1.8  [23]

можно заменить квадратные скобки в генераторах массивов круглыми скобками и получить выражения-генераторы. Выражение-генератор похоже на генератор массивов (синтаксис в круглых скобках в точности соответствует синтаксису в квадратных скобках), но его значением является объект генератора, а не массив. Преимущество выражений-генераторов перед генераторами массивов в том, что они используют прием отложенных вычислений - вычисления выполняются по мере необходимости, а не все сразу - и позволяют обрабатывать даже бесконечные последовательности. Недостаток генераторов состоит в том, что они обеспечивают только последовательный доступ к своим элементам. То есть, в отличие от массивов, генераторы не позволяют обращаться к элементам по индексам: чтобы получить n-е значение, придется выполнить n-1 итераций.

Ранее в этой главе мы реализовали функцию map():

<b>// Функция-генератор, возвращающая f(х) для каждого элемента х итерируемого объекта і</b>

<b>function map(і. f) {</b>

<b>  fоr(let x in і) yield f(x);</b>

<b>}</b>

Выражения-генераторы позволяют избежать необходимости создавать или использовать такую функцию map(). Чтобы получить новый генератор h, возвращающий f (х) для каждого значения х, возвращаемого генератором g, достаточно использовать такой программный код:

<b>let h = (f(x) for (x in g));</b>

Используя генератор eachline() из примера 11.1, можно реализовать отсечение пробельных символов, а также фильтрацию комментариев и пустых строк, как показано ниже:

<b>let lines = eachline(text);</b>

<b>let trimmed = (l.trim() for (1 in lines));</b>

<b>let nonblank = (1 for (1 in trimmed) if (1.length &gt; 0 &amp;&amp; 1[0]!='#'));</b>

11.5. Краткая форма записи функций

В JavaScript 1.8 [24]

появилась возможность краткой записи простых функций (называется «лексическим замыканием»). Если функция вычисляет единственное выражение и возвращает его значение, ключевое слово

<b>return</b>
и фигурные скобки, окружающие тело функции, можно опустить и просто поместить выражение сразу после списка аргументов. Например:

<b>let succ = function(x) х+1, yes = function() true, no = function() false;</b>

Это просто и удобно: функции, определяемые таким способом, ведут себя как обычные функции, в определении которых присутствуют фигурные скобки и ключевое слово

<b>return</b>
. Этот сокращенный синтаксис удобно использовать, в частности, при передаче функций другим функциям. Например:

<b>// Отсортировать массив в обратном порядке </b>

<b>data.sort(function(a,b) b-a);</b>

<b>// Определение функции, которая возвращает сумму квадратов элементов массива</b>

<b>let sumOfSquares = function(data)</b>

<b>  Array.reduce(Array.map(data, function(x) x*x), function(x,y) x+y);</b>

11.6. Множественные блоки catch

В JavaScript 1.5 инструкция

<b>try/catch</b>
была добавлена возможность использовать несколько блоков
<b>catch</b>
. Чтобы использовать эту возможность, необходимо, чтобы за именем параметра блока
<b>catch</b>
следовало ключевое слово
<b>if</b>
и условное выражение:

<b>try {</b>

<b>  // здесь могут возбуждаться исключения нескольких типов</b>

<b>  throw 1;</b>

<b>}</b>

<b>catch(e if е instanceof ReferenceError) {</b>

<b>  // Здесь обрабатывается исключение обращения к неопределенному имени</b>