Массивы (Firefox 30-57)
Примечание: понимание массива никогда не было стандартизировано и устарело в Firefox 58. Используйте на свой страх и риск.
Первоначально спецификация ECMAScript 7 содержала множество новых функций на основе массива. Хотя большинство из них не вошли в финальную версию, поддержка Firefox (ed), возможно, самая большая из этих функций: новый модный синтаксис, который можно заменить, .filter
и .map
с for(a of b)
синтаксисом. Вот пример:
b.filter(a=>/\s/.test(a)).map(a=>a.length)
[for(a of b)if(/\s/.test(a))a.length]
Как видите, две строки не так уж отличаются, кроме второй, не содержащей громоздких ключевых слов и функций стрелок. Но это только объясняет порядок .filter().map()
; что произойдет, если у вас есть .map().filter()
вместо этого? Это действительно зависит от ситуации:
b.map(a=>a[0]).filter(a=>a<'['&&a>'@')
[for(a of b)if(a<'['&&a>'@')a[0]]
b.map(a=>c.indexOf(a)).filter(a=>a>-1)
[for(a of b)if((d=c.indexOf(a))>-1)d]
b.map(a=>a.toString(2)).filter(a=>/01/.test(a))
[for(a of b)if(/01/.test(c=a.toString(2)))c]
Или что, если ты хочешь или .map
или .filter
? Ну, обычно получается меньше, хорошо
b.map(a=>a.toString(2))
[for(a of b)a.toString(2)]
b.filter(a=>a%3&&a%5)
[for(a of b)if(a%3&&a%5)a]
Так что мой совет использовать постижения массива , где вы обычно используете .map
и .filter
, но не только один или другие.
Строковые Понимания
Хорошая вещь в понимании ES7 состоит в том, что, в отличие от функций, специфичных для массива, таких как .map
и .filter
, они могут использоваться с любым итерируемым объектом, а не только с массивами. Это особенно полезно при работе со строками. Например, если вы хотите запустить каждый символ c
в строке через c.charCodeAt()
:
x=>[...x].map(c=>c.charCodeAt())
x=>[for(c of x)c.charCodeAt()]
Это два байта, сохраненные в довольно небольшом масштабе. А что если вы хотите отфильтровать определенные символы в строке? Например, этот хранит только заглавные буквы:
x=>[...x].filter(c=>c<'['&&c>'@')
x=>[for(c of x)if(c<'['&&c>'@')c]
Хм, это не короче. Но если мы объединим два:
x=>[...x].filter(c=>c<'['&&c>'@').map(c=>c.charCodeAt())
x=>[for(c of x)if(c<'['&&c>'@')c.charCodeAt()]
Вау, целые 10 байтов сохранены!
Еще одним преимуществом понимания строк является то, что жестко закодированные строки сохраняют дополнительный байт, так как вы можете опустить пробел после of
:
x=>[...'[](){}<>'].map(c=>x.split(c).length-1)
x=>[for(c of'[](){}<>')x.split(c).length-1]
x=>[...'[](){}<>'].filter(c=>x.split(c).length>3)
x=>[for(c of'[](){}<>')if(x.split(c).length>3)c]
индексирование
Понимание массива затрудняет получение текущего индекса в строке / массиве, но это можно сделать:
a.map((x,i)=>x+i).filter ((x,i)=>~i%2)
[for(x of(i=0,a))if(++i%2)x+i-1]
Главное, о чем следует помнить, это убедиться, что индекс увеличивается каждый раз, а не только при выполнении условия.
Генератор понимания
Генераторные понимания имеют в основном тот же синтаксис, что и массивы; просто замените скобки на круглые скобки:
x=>(for(c of x)if(c<'['&&c>'@')c.charCodeAt())
Это создает генератор, который работает почти так же, как массив, но это история для другого ответа.
Резюме
В принципе, хотя понимание обычно короче .map().filter()
, все сводится к специфике ситуации. Лучше всего попробовать оба способа и посмотреть, что получится лучше.
PS Не стесняйтесь предложить другой связанный с пониманием совет или способ улучшить этот ответ!