Почему недавний переход к удалению / исключению точек с запятой из Javascript?


80

В последнее время кажется модным опускать точки с запятой в Javascript. Несколько лет назад был пост в блоге, в котором подчеркивалось, что в Javascript точки с запятой необязательны, и суть поста заключалась в том, что вам не следует беспокоиться о них, потому что они не нужны. Эта публикация, на которую часто ссылаются, не дает никаких веских причин не использовать их, только то, что ее исключение имеет мало побочных эффектов.

Даже GitHub запрыгнул на точку с запятой без точки с запятой, требуя их пропуска в любом внутренне разработанном коде, а недавняя фиксация его сопровождающим проекта zepto.js удалила все точки с запятой из кодовой базы. Его главные оправдания были:

  • это вопрос предпочтения его команды;
  • меньше печатать

Есть ли другие веские причины, чтобы оставить их?

Честно говоря, я не вижу причин для их пропуска и, конечно, нет причин возвращаться к коду, чтобы стереть их. Это также идет вразрез с ( многолетней ) рекомендуемой практикой , за которую я на самом деле не покупаю аргумент "культа груза". Итак, почему все последние точки с запятой ненавидят? Есть надвигающаяся нехватка? Или это всего лишь последнее увлечение Javascript?


2
«годы рекомендованной практики» относятся к вопросу о внесении в черный список тегов опросов SO, которые вряд ли делают его авторитетным для поддержки любого мнения
комнат

24
@gnat только потому, что люди ненавидят вопрос о SO, не делает его менее достоверным источником мнения людей.
Ryathal

3
@gnat Вопросы, которые «официально считаются неприемлемыми в StackOverflow» , иногда рассматриваются экспертным сообществом как очень авторитетные. Грустно, но правда.
MarkJ

4
@gnat Вопрос в черном списке на самом деле имеет несколько очень интересных примеров того, почему опущение ;может нарушить ваш код. Так что я бы сказал, что это полезная ссылка на этот вопрос.
Андрес Ф.

1
Это может быть связано с растущей известностью хипстеров в начале 2010-х годов.
Алекс

Ответы:


62

Я полагаю, что причина в том, что у меня самая слабая причина: я программирую на слишком многих языках одновременно (Java, Javascript, PHP) - для которых требуется ';' так что вместо того, чтобы тренировать мои пальцы и глаза, что ';' не нужен для javascript, я просто всегда добавляю ';'

Другая причина - документация: добавив ';' Я прямо заявляю себе, где я ожидаю, что заявление закончится. Тогда я снова использую {} тоже все время.

Весь аргумент подсчета байтов я нахожу раздражающим и бессмысленным:

1) для распространенных библиотек, таких как jquery: используйте Google CDN, и библиотека, вероятно, уже будет в кеше браузера

2) версия ваших собственных библиотек и установить их кеширование навсегда.

3) gzip и сверните, если действительно, действительно необходимо.

Но на самом деле, сколько сайтов имеют наибольшее ограничение скорости загрузки своего javascript? Если вы работаете на топ-100 сайтов, таких как Twitter, Google, Yahoo и т. Д., Может быть. Остальным следует беспокоиться о качестве кода, а не о точках с запятой в религиозных войнах.


3
Полагаю, обратное тоже может быть правдой. По мере того, как python становится все более популярным для Интернета, ваш JS становится похожим на python.
Бен ДеМотт

4
Попробуйте, но тогда те же самые байтовые воины будут за мной за ненужными пробелами в начале строк. (У меня также будут ошибки в Javascript, потому что я буду полагаться на правило отступа Python, а не на использование {}
Пэт

6
Если важно уменьшить количество байтов, у вас будет что-то, что максимально минимизирует файлы. Если пока не стоит использовать минимизатор, не стоит беспокоиться об удалении ';' сэкономить на счет байтов.
Lawtonfogle

3
Количество байтов на самом деле не обязательно сокращается, фактически оно может быть увеличено, так как новая строка часто (не всегда) на самом деле состоит из двух символов (новая строка, за которой следует возврат каретки), поэтому в своей наиболее компактной форме новая строка будет однажды символом, таким же, как односимвольная точка с запятой (если вы сжимаете весь код JS в одну строку, что часто делается для развернутого кода JS, а не исходного кода разработки).
ALXGTV

Людям нужно углубление, чтобы понять глубокое вложение, которое требует больше байтов, чем точек с запятой. Точка с запятой - это отвлекающая трата клавиш.
Сис Тиммерман

39

Это облегчает создание цепочек методов и делает их более чистыми.

Так скажем, я спрашиваю о и у меня есть

$('some fancy selector')
  .addClass()
  .attr();

Если я хочу добавить что-то и оставить свой коммит на основе строки маленьким , я должен добавить его выше attr. Так что это одна мысль дольше, чем просто «добавить в конце». А кто хочет думать? знак равно

$('some fancy selector')
  .addClass()
  // new method calls must go here
  .attr();

Но когда я опускаю точки с запятой, я могу просто добавить и назвать это день

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate()
+   .click()

Кроме того, если я решу отключить последний метод, мне не придется переназначать точку с запятой и снова загрязнять свой коммит.

  $('some fancy selector')
    .addClass()
    .attr()
    .animate()
-   .click()

Против угго

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate();
-   .animate()
-   .click();

37
Это нишевый вариант использования IMO.
Дж. Б. Уилкинсон,

9
Но все же интересно.
Джонатан

8
Вы можете поставить точку с запятой в конце новой строки с отступом в качестве начальной строки. Затем вы копируете и изменяете порядок вещей по своему желанию. Это также хорошо замыкает цепь.
Nux

11
Только я задаюсь вопросом, почему кого-то должно волновать, насколько аккуратны различия их коммитов? как правило, люди читают код, а не различий.
Жюль

11
@Jules, более чистые различия означают, что слияния с большей вероятностью будут успешными.
Joeytwiddle

22

точки с запятой в JavaScript являются необязательными

Моя личная причина не использовать точку с запятой - ОКР.

Когда я использую точки с запятой, я забываю 2% из них и должен постоянно проверять / добавлять их обратно.

Когда я не использую точки с запятой, я никогда не вставляю их случайно, поэтому мне никогда не нужно проверять / удалять их.


3
Хороший. Я был записан строкой без двоеточия или двумя в файле с правильной точкой с запятой.
Джонатан

3
Существуют парсеры (например, GeSHi), которые не будут правильно анализировать ваш код, если точки с запятой отсутствуют. Вы могли бы сказать, что люди не будут совершать таких ошибок ... А если серьезно, если вся ваша команда сумеет вспомнить, куда нужно ставить точки с запятой, вы действительно думаете, что они запомнят это без утреннего кофе? И они будут кодировать во многих состояниях ума. Будьте уверены в этом.
Nux

16

Недавно я написал анализатор / анализатор для JavaScript, где мне пришлось тщательно внедрить ASI, и у меня также есть моя копия Крокфорда JavaScript: The Good Parts на моей книжной полке, которая рекомендует всегда использовать точки с запятой. Намерение было хорошим, но оно не всегда помогает на практике.

Очевидно, что люди, пишущие фреймворки, такие как jQuery, zepto и т. Д., Являются мастерами синтаксиса JavaScript, и поэтому они знают разницу между:

return
{
    status: true
};

а также

return {
    status: true
};

JavaScript, хотя и мощный, также является языком для начинающих, и удача объясняет это тому, кто только изучает, что такое forцикл. Как и при знакомстве большинства людей с новым навыком, есть некоторые более сложные вещи, которые вы не хотите сразу объяснять, поэтому вместо этого вы решаете привить «культу груза» веру в определенные вещи просто для того, чтобы оторваться от земли. Итак, у вас есть два варианта при обучении новичка написанию JavaScript:

  1. Скажите им «следовать этому одному правилу и не спрашивайте , почему», говоря им поставить всегда точку с запятой в конце каждой строки. К сожалению, это не помогает в приведенном выше примере или в любом другом примере, где ASI мешает. И мистер или миссис начинающий программист растерялся, когда вышеприведенный код потерпел неудачу.
  2. Скажите им: «следуйте этим двум правилам и не спрашивайте, почему», сказав им не беспокоиться о точках с запятой в конце каждой строки, а вместо этого всегда: а) Следовать returnс помощью {а и б) Когда строка начинается с а (, предварительно это с ;.

Выбор варианта 2 - это лучший набор правил «культа груза», которым нужно следовать (приведет к очень небольшому количеству ошибок, связанных с ASI), и даже если вы действительно глубоко разберетесь в теме, у вас будет меньше ненужных символов на экране.


8
Хорошо, я укушу. Помогите мне понять разницу в синтаксисе между двумя примерами выше. Мой неподготовленный глаз видит только разницу в форматировании.
Джесси С. Slicer

9
Или, с другой стороны, я наткнулся на ответ по чистой случайности. В первом примере returnоператор рассматривается как отдельный оператор, а конец строки является эквивалентом точки с запятой. Второй пример фактически возвращает объект. Трикси.
Джесси С. Slicer

9
Я не думаю, что могу согласиться с идеей, что JavaScript - это язык для начинающих, в JavaScript есть множество несоответствий и неожиданных эффектов, которые не имеют простых объяснений. IMO, язык для начинающих не будет таким, я бы назвал JavaScript промежуточным языком.
Ryathal

2
@Ryathal Я понимаю, к чему вы клоните, но называя его промежуточным языком, я задаюсь вопросом, на каких языках он взаимодействует. Это звучит так, как будто это шаг в путешествие к чему-то другому, а не пункт назначения сам по себе.
Рашит

9
Пояснение: returnпример на самом деле является исключением из обычного поведения JS, которое заключается в попытке объединить строки, если точка с запятой не указана. return, breakи continueвсе демонстрируют это исключительное поведение, при котором завершающий символ новой строки всегда интерпретируется как конец утверждения. (Источник - «JavaScript: полное руководство» Фланагана, стр. 25-26). Лично я стремлюсь к идее «кода наименьшего удивления». Отсутствие точек с запятой имеет тенденцию приводить к большему количеству неожиданностей, чем что-либо еще (я обычно также держу свои фигурные скобки даже для простых утверждений).
Кайл

16

Нет такой вещи как информационная перегрузка, только плохой дизайн.

- Эдвард Туфте

Это общее правило в графическом дизайне, чтобы исключить ненужные элементы и украшения, чтобы уменьшить шум.

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

let foo = 1

против

let /* variable */ foo = 1; // EOL

Конечно, это преувеличенный пример, но он иллюстрирует общий принцип: дополнительные визуальные элементы следует добавлять тогда и только тогда, когда они служат цели. Итак, точки с запятой служат цели?

Историческими причинами использования точек с запятой в JavaScript были:

  • Поддерживать сходство с C / Java
  • Избегайте проблем совместимости с плохо написанными браузерами и инструментами
  • Помощь людям и машинам в обнаружении ошибок кода
  • Автоматическая вставка точки с запятой влечет за собой снижение производительности

Проблемы совместимости сегодня в значительной степени не проблема. Современный пух может обнаружить любые ошибки в коде точно так же без запятой. Сходство с C / Java / PHP все еще может быть предметом рассмотрения (см. Принятый ответ Пат), но только потому, что другие языки содержат лишние синтаксические элементы, не означает, что мы должны хранить их в JavaScript, тем более что многие другие языки (Coffeescript, Python, Руби, Скала, Луа) не требуют их.

Я сделал быстрый тест, чтобы увидеть, есть ли снижение производительности в V8. Это Io.js, анализирующий файл JavaScript 41 МБ (Lodash повторяется 100 раз) с точками с запятой, а затем с удаленными точками с запятой:

$ time node lodashx100.js
node lodashx100.js  2.34s user 1.30s system 99% cpu 3.664 total
$ time node lodashx100s.js
node lodashx100s.js  2.34s user 1.15s system 99% cpu 3.521 total

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


Я бы противопоставил этому аргументу пропуски ненужных элементов в нагрузке, которую ум должен теперь сделать, чтобы добавить необязательный синтаксис. Теперь точка с запятой не является огромным умственным напряжением, если ее опустить. Это проблема, с которой я столкнулся в Ruby и Scala. Когда он превращается в цепочку звонков с звонками внутри звонков, и все они опускаются на каждого парена, бремя разлучать - это бремя.
Симус

8

Выбор соглашения о программировании фактически совпадает с выбором подмножества целевого языка. Мы все делаем это по обычным причинам: удобочитаемость кода, удобство обслуживания, стабильность, переносимость и т. Д., При этом жертвуя гибкостью. Эти причины являются реальными деловыми причинами.

Такие причины, как «сохранение нажатий клавиш» и «программисты должны изучать правила JavaScript», являются незначительными бизнес-причинами, поэтому они имеют небольшой практический вес.

В моем случае мне нужно было очень быстро освоить JavaScript, поэтому использование ограниченного подмножества языка было в моих интересах. Поэтому я выбрал JSLint-подмножество JavaScript, включил JSLinter-приложения Rockstar в Eclipse с самыми строгими настройками, которые я мог выдержать, и не оглядывался назад.

Я благодарен за возможность избежать деталей разницы между "==" и "===" или деталей вставки точек с запятой, потому что у меня уже есть список задач высотой в милю, а эти детали не будут помочь сделать эти работы на секунду раньше.

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


5

Довольно старый вопрос, однако я удивлен, что никто не упомянул:

Минификация: если вам случится минимизировать фрагмент JavaScript, который явно не заканчивает операторы символом точки с запятой, вы можете столкнуться с трудностями, пытаясь выяснить, что не так с фрагментом, который только работал до минификации и сейчас не работает.

Неоднозначность: точка с запятой необязательна, правда, однако, исключив их из исходного кода, вы можете оставить некоторые неоднозначные сценарии анализатору, чтобы он сам решал. Если вы пишете 100 строк кода для интернет-магазина, да, возможно, это не имеет значения, но более серьезные задачи требуют 100% ясности.

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

Почему это становится все более популярным в наши дни?

Я лично считаю, что выполнение JavaScript на стороне сервера оказало большое влияние на само сообщество JavaScript. В нашем случае, очевидно, никто не собирается минимизировать JavaScript на стороне сервера (так как исходный код не должен отправляться в веб-браузер клиента), поэтому отсутствие двоеточий выглядит намного безопаснее, что верно; однако другие разработчики, которые учатся на этих книгах, статьях и видео, к сожалению, отвергают тот факт, что JavaScript на стороне сервера не совсем то же самое, что JavaScript на стороне клиента.


Минифайеры могут выходить в односимвольных переводах строк или вставлять точки с запятой, когда точки с запятой отсутствуют без штрафа за размер. Я не знаю, какие (если таковые имеются) минифайеры делают это. Опасность все еще существует, по крайней мере, в некоторых из них, так что ваша точка зрения остается на практике.
outis

3

Есть веские причины, чтобы держать их.

Они не являются обязательными, JS может добавить их обратно с автоматической вставкой точки с запятой, если они отсутствуют, но это не одно и то же.

JavaScript Дугласа Крокфорда: «Хорошие детали» в двух разных случаях говорит, что это плохая идея. Автоматическая вставка точки с запятой может скрывать ошибки в вашей программе и создает неоднозначность.

JSLint не одобряет.


3

JavaScript не нуждался в точках с запятой для завершения операторов в течение более десяти лет. Это потому, что символы новой строки считаются терминаторами операторов (я полагаю, это также упоминалось в ранних спецификациях ECMAScript). Это действительно имеет большой смысл, особенно потому, что на самом деле нет веской причины (о которой я знаю), почему JavaScript должен часто использовать точки с запятой, а не другие интерпретируемые декларативные языки, такие как Ruby или Python.

Требование точки с запятой может облегчить написание синтаксического анализатора для языка, но если каждый интерпретатор там поддерживает пропуск точки с запятой, то в чем именно смысл?

Все сводится к тому, насколько опытен программист: если вы знаете, что можете пропустить точку с запятой, не стесняйтесь делать это, понимая, что это может или не может быть следствием. Люди являются машинами для принятия решений, и почти все решения требуют некоторого компромисса или компромисса. Компромисс между простым добавлением точек с запятой по всему коду (даже в тех местах, где они не нужны) заключается в том, что ваш код становится менее читабельным (в зависимости от того, кого вы спрашиваете), и JSLint не будет жаловаться (кого это волнует) ). С другой стороны, компромисс с пропуском точек с запятой заключается в том, что 90% программистов JavaScript будут наказывать вас за это, но вы можете в конечном итоге получить больше удовольствия от написания JavaScript из-за этого.

Что звучит лучше для вас; принятие обоснованных решений или слепое принятие решений / стадный менталитет?


Мне было бы интересно узнать, почему это получило отрицательные отзывы. JavaScript не нуждается в точках с запятой для завершения операторов; он, конечно, может их использовать, но они ни в коем случае не являются обязательным требованием. Если бы они были необходимы, то ничто другое объяснение не сработало бы. Факт (да, факт), что вы можете написать целое приложение JavaScript с несколькими точками с запятой или без, демонстрирует это. Кроме того, я не вижу, как понимание того, как работает инструмент, и использование собственных аргументов для принятия решений как-то нежелательно в отличие от «просто сделай это». Это то, что известно как религия.
Равенстин

Я не отрицал, но проблема может заключаться в том, что это на самом деле не так, как написано. Переводы строк не считаются разделителями операторов в JavaScript. Вы можете пропустить точку с запятой из-за функции, называемой автоматической вставкой точки с запятой, которая позволяет автоматически исправлять ошибки синтаксического анализа при определенных обстоятельствах. Люди, которые защищают точки с запятой, утверждают, что многие программисты на javascript плохо понимают это правило. Ваш пост кажется аргументом в их пользу в этом свете. (Справедливости ради, я в основном согласен с вашим тезисом, но по разным причинам)
Тим Сегин

@TimSeguine Да, я написал это прежде, чем у меня было лучшее понимание. Я все еще не думаю, что объективно неправильно не использовать точки с запятой, пока люди, которые это делают, понимают, что именно они делают. Я должен переделать свой пост или, возможно, избавиться от него, так как об этом поделились многие другие. Спасибо за вежливую критику! :)
Равенстайн

2

У меня есть две теории:

A)

Суть этого выбора в том, что когда-то, когда JSLint и т. Д. Были применимы, вы предпочитали тратить большое количество времени на отлов неясных синтаксических ошибок или разумное количество времени для реализации политики стандартов в коде.

Однако по мере того, как мы все больше движемся в сторону кода, основанного на модульном тестировании, и непрерывной интеграции, время (и взаимодействие с человеком), необходимое для обнаружения синтаксической ошибки, значительно уменьшилось. Отзывы от тестов быстро укажут, работает ли ваш код должным образом, задолго до того, как он приблизится к конечному пользователю, так зачем тратить время на добавление дополнительной детализации?

B)

Ленивые программисты сделают все, чтобы облегчить себе жизнь в краткосрочной перспективе. Меньше печатать -> меньше усилий -> проще. (кроме того, отсутствие точки с запятой поможет избежать напряжения безымянного пальца правой руки и избежать RSIness).

(NB. Я не согласен с идеей пропустить что-то, что устраняет неоднозначность утверждения).


1
Jshint по-прежнему является важным инструментом.
Рэйнос

Что касается неоднозначности заявления, оба \nи ;\nодинаковы
Raynos

2
@Raynos На самом деле, я обнаружил, что JSLint имеет тенденцию быть немного бесполезным из-за сложности некоторого кода с большим количеством фреймворков, с которым я часто работаю. Кроме того,; \ n и \ n не одинаковы при любых обстоятельствах , иначе в них никогда не было бы необходимости;
Эд Джеймс

7
jslint бесполезен, однако jshint - это другой инструмент.
Рейнос

0

Я не пропускаю их, но я меняю правила, когда их вставлять.

Правила, которые используют большинство людей,

  • Перед каждым окончанием строки
  • За исключением того, что строка заканчивается }приходом из оператора функции
  • Но только оператор функции, а не присвоение литералу функции

Мое правило таково: в начале каждой строки, начинающейся с открывающей скобки / скобки.

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


Другой аргумент в том, что печально известная return\nvalueошибка возникает из-за незнания ASI. Мое правило заставляет вас знать об ASI, поэтому люди, использующие мое правило, с меньшей вероятностью попадут в ловушку этой ошибки.


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.