openlang

Массив, о котором никто не просил

CoffeeScript возвращает последнее выражение любой функции, а цикл for - тоже выражение. Поэтому обработчик, который заканчивается циклом ради побочных эффектов, компилируется в JavaScript, который собирает значение каждой итерации в массив и возвращает его. Этот массив никто не читает. Документация советовала заканчивать такие функции на true или null, и я до сих пор ловлю себя на том, что ставлю в конце null в обычном JavaScript, где он ничего не делает.

Разговор продолжается 4

Следуя доводам
  1. Ссылка на ответ

    ReScript тоже возвращает последнее выражение, но такой массив не строит, потому что цикл for там имеет тип unit. На неиспользованное значение посреди блока выдаётся предупреждение с советом обернуть его в ignore, и чему это учит новичка, мне не очень ясно.

  2. Ссылка на ответ

    Массив - это ещё безобидный случай. Интереснее обработчик, у которого последняя строка случайно оказалась булевой.

    Если обработчик повешен через addEventListener, возвращаемое значение игнорируется, и всё, что дали цикл или сравнение, просто мусор. Если он присвоен onclick, возвращённый false отменяет действие по умолчанию. Если это обработчик jQuery, false ещё и останавливает всплытие, потому что jQuery считает его вызовом preventDefault() вместе со stopPropagation(). Выходит, один и тот же скомпилированный return в одной схеме шум, в другой ссылка, по которой не перейти, а в третьей клик, о котором родитель так и не узнает.

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

  3. Ссылка на ответ

    Вот это наломало дров больше, чем массивы (и подозреваю, что совет вообще появился наполовину из-за этого, ведь хвостовой null или true jQuery не трогает, а случайный false трогает, и документация так и не сказала это прямо). Обычной жертвой был переключатель. Обработчик клика, который заканчивается на @open = not @open, компилируется в return this.open = !this.open; и возвращает false на каждом втором клике. Каждый второй клик переключал панель и заодно съедал событие. Выглядит как капризный переключатель, пока не прочитаешь скомпилированную строку с возвратом, а её очень легко проскочить глазами.

  4. Ссылка на ответ

    В обычном JavaScript осталась стрелочная функция без фигурных скобок. useEffect(() => fetchList()) отдаёт React промис, и консоль в режиме разработки ругается, а useEffect(() => { fetchList() }) возвращает undefined, примерно для этого и был тот хвостовой null.

Другие стороны того же вопроса

  1. round(2.5) даёт 2, и ученики не верят

    Ученики упорно думают, что round(2.5) равно 3, а оба языка, к которым я обычно тянусь, говорят 2. Python даёт целое 2, Julia…

    Ответы 4juliapython
  2. 3 + 4 * 2 равно 14, и это ещё простая часть

    Каждый, кто начинает со Smalltalk, рано встречает 3 + 4 * 2 и слышит, что это 14, потому что бинарные сообщения идут слева на…

    Ответы 1smalltalk
  3. Ручной перевод старого CoffeeScript как урок JavaScript

    Немодное упражнение, которое работает лучше, чем имеет на то право. Дайте ученику небольшой старый файл на CoffeeScript и поп…