Pull to refresh

Comments 20

Супир. Засунул и в свой проект тоже. Видел его, но в какой-то момент отвлёкся на что-то и пропустил впоследствии.

Не понимаю чем for in/of не угодил.
Поддерживаю, и более того, forEach нельзя остановить в нужный момент. Давайте выбирать нужный инструмент для нужного момента а не становиться жертвами моды.
и более того, forEach нельзя остановить в нужный момент.

Если нужно что-то остановить в нужный момент — вы можете использовать some или every для таких ситуаций, что больше нравится. В нужный момент будет достаточно вернуть true/false, чтобы завершить ход итерации.


P.S. И называть лучшие практики, основанные на большом опыте специалистов, "модой" — это такое себе конечно, да.

Т.е. вы предлагаете полностью отказаться от циклов for и while? Вы только с массивами работаете?

Вообще, я не сильно против них :)) Но в целом, да, для своего проекта я это правило добавил, ибо перебирающие методы на основе анонимных функций сейчас мы у себя используем везде, они выглядят приятнее. Соответственно, почему бы и не сделать подобное правило для себя) В проекте было всего несколько циклов for, которые нашёл линтер с этим плагином — и мне действительно захотелось их переписать, чтобы сделать эти места чуть более приятными.


P.S. Ну и с другой стороны, никто не запрещает использовать циклы в качестве исключения, отключив это правило на определённой строке кода в своём проекте, как и пишет автор этого плагина у себя на странице:


If 99% of your code doesn't need them, but you have that single case where a loop makes sense, go ahead!

// eslint-disable-next-line no-loops/no-loops
for (let i = 0; i < arr.length; i++) {
  // ...
}
Ну так а какие вы знаете способы перебрать, скажем, генератор, не используя for of? Приводить все сперва к массиву? А в чем тогда суть генераторов?

Да нет проблем, если вы активно используете генераторы — то не берите себе это правило. Мы их у себя не используем, соответственно я не вижу необходимости в for, для нашего текущего проекта)

И называть лучшие практики, основанные на большом опыте специалистов, "модой" — это такое себе конечно, да.

А какое отношение имеет отказ от базовых конструкций языка для итерирования коллекций к "большому опыту" каких-то там "специалистов"?


они выглядят приятнее

for(const item of collection) // 1
   handle(item); 
for(const item of collection) // 2
   item.handle();
for(const item of collection) // 3
   item.handle(something); 
for(const item of collection) // 4
   await item.handle(something); 
for(const item of collection) // 5
   await item.handle(await some(item.id)); 

collection.forEach(handle); // 1
collection.forEach(item => item.handle()); // 2
collection.forEach(item => { item.handle(); }); // 2 right way
collection.forEach(item => { item.handle(something); }); // 3 
collection.reduce((prev, item) => prev.then(item.handle(something))), Promise.resolved()); // 4  
coll... oh, sh... // 5

Визуально, на мой вкус, конструкции с for-of выглядят куда опрятнее. Глаз воспринимает их мгновенно. Не в последнюю очередь из-за подсветки синтаксиса для const и for и of). К тому же они не располагают писать всё в одну строку (как это делают часто в случае функциональных примитивов, чтобы не прибегать к {}). Не содержат лишнего визуального шума.


А ещё они более дурако-баго-устойчивы. Начинающие и продолжающие часто наступают на эти грабли. Причём иногда это может отнять часы дебага. Тут я имею ввиду:


  • доп. аргументы + сокращённые записи (.forEach(method)).
  • реакции на return (_.forEach(arr, item => item.handle()).

Учитывая, что forEach не chain-ится, то я часто применяю for-of вместо .forEach в угоду читаемости кода. Но избегаю этого, скажем, если .forEach выступает финальным методом цельной цепочки, чтобы её не рвать попусту.


Пример с forEach хорошо показывает суть линтеров. Это огромное количество друг другу противоречащих правил, почтив все из который чуть более, чем полностью субъективны. Но! Они позволяют вручную настроить тот баланс, который будет удобнее вам и вашей команде. Можно отключить всё лишнее, дописать своё, настроить существующее и т.д… Как ребята из airbnb и сделали. Да и многие, я уверен, делают.


Можно конечно вслепую следовать чужим рекомендациям, "специалистов" с "большим опытом". Но не факт, что вам это хоть что-то даст. Использование каких-то насильственных ограничений без понимания природы этих ограничений мне кажется довольно наивным. Использование этих ограничений исходя из потребностей команды и проекта — может быть очень продуктивным. Настройка eslint-а под вкусы и нужды конкретно взятого тимлида может легко отнять пару дней :)

Это всё понятно. Но это, по сути, единственное исключение из правил: конструкция for ... of. Все остальные три варианта, или сколько их там всего: for (...), for ... in и while в целом я лично могу посчитать менее приятными и полезными. Я нигде ни разу и не написал здесь что-то в таком ключе, что эти правила были ниспосланы вам Свыше, и никто их не имеет права нарушать. Нарушайте, какие проблемы.

Ну так наверное это 99% кода в целом. Конструкции for-in и for(;;) исключительно редко нужны. А чем вам while не угодил? Как вы его заменяете? В Ramda для этого есть свой функциональный аналог? R.while(condition)(callback)? :)


что эти правила были ниспосланы вам Свыше

Примерно это вы и написали. Народ решительно недоумевает зачем это странное правило вы вообще упомянули в статье.

Да нет проблем: недоумевайте сколько пожелаете, сколько раз я вам это уже написал?) И займитесь чем-нибудь полезным в том числе. Этот плагин из раздела "дополнительные плагины", если вам он не понадобился — не используйте.


while я лично просто не использовал уже несколько лет. Не могу вспомнить ситуацию, в которой нельзя было написать логику так, чтобы обойтись без него. Соответственно, мне эта языковая конструкция сейчас просто не нужна, и я могу спокойно добавить её в список того, что можно не использовать в проекте. Вы можете делать что хотите, можете вообще не использовать линтеры или даже написать свой собственный конфиг, если конфиги из текущего списка вам не нравятся — статья примерно на эту тему, надеюсь в будущем вы будете обращать на это внимание. Господи, как всегда в нашей стране: напишешь что-то людям, они потом начинают тебя со всех сторон обсасывать и искать в твоих словах ошибки, даже тогда, когда ты им в тридцатый раз всё подробно объяснил. Не обижайтесь, на ваши сообщения больше отвечать не буду, займусь другими более полезными делами.

Не понимаю чем for in/of не угодил.

Их запрещает даже не какой-то плагин к eslint'у, а сам eslint:


[eslint] for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array. (no-restricted-syntax)

[eslint] iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations. (no-restricted-syntax)
>require regenerator-runtime

Генераторы в Firefox поддерживаются с 2013 года, в Chrome и Opera с 2014 года, в Edge с 2015, в Safari с 2016. И это не говоря про node.js. Так что, может, уже можно без regenerator?

Видимо всё так, значит это правило уже неактуально и его можно игнорировать.

И вот так с каждым первым-вторым-третьим правилом. Только после тщательного анализа причин и следствий имеет смысл их применять. К примеру подключив какой-нибудь готовый пак правил — пробежаться по своему коду, изучить warning-и и заняться выпиливанием лишних мусорных правил, детальной настройкой оставшихся, возможно поиском новых.


Скажем из пака lodash/recommended я отключил 10 штук. Из пака react два. .eslint в 138 строк. И это я ещё не самый дотошный человек.


Мне кажется в вашей статье не хватает этого пояснения где-нибудь вначале. Простое подключение чьих либо готовых ограничений скорее отвратит человека от eslint-а, нежели поправит ему руки. Даже когда эти ограничения действительно полезны ему лично.

Я рискую оказаться в меньшинстве, но для меня связка TypeScript в режиме JS + Prettier оказалась более продуктивной. Статическая типизация ловит как опечатки, так и более сложные ошибки. А за стилем следит Prettier.


А в ESLint, как по мне, слишком много неоднозначных настроек. Вот например, что в этом коде не так?


const { id, name } = user;
// [eslint] 'name' is already declared in the upper scope. (no-shadow)

А вот что: Window.name!


Или вот valid-jsdoc. Хочешь ты написать просто пояснение к методу. Но нет! Напиши еще и @param с описанием каждого параметра (как правило тавтология) и @returns.


Это все конечно правильно. Но отнимает время. И некоторые разработчики просто поленятся написать документацию к методу.

:) Да тоже нормально, почему нет. Prettier мы точно также используем для своего проекта, да. Он позволяет автоматически исправлять большую часть ошибок, на которые указывает eslint. Тайпскрипт/flow нынче тоже популярны, но сейчас я лично их не использую, поэтому и не писал про них)

Кстати, у меня в проекте на переменную name eslint не ругается. Не знаю как у вас такое возникло)

Sign up to leave a comment.

Articles