Сегодня мы публикуем перевод следующей части руководства по JavaScript. Здесь мы поговорим о стиле кода и о лексической структуре программ.
→ Предыдущая часть (первая программа, особенности языка, стандарты)
Стиль программирования
«Стиль программирования», или «стандарт кодирования», или «стиль кода» — это набор соглашений, которые используются при написании программ. Они регламентируют особенности оформления кода и порядок использования конструкций, допускающих неоднозначности. В нашем случае речь идёт о программах, написанных на JavaScript. Если программист работает над неким проектом сам, то стиль кода, применяемый им, представляет его «договор» с самим собой. Если речь идёт о команде, то это — соглашения, которые используются всеми членами команды. Код, написанный с применением некоего свода правил, делает кодовую базу программного проекта единообразной, улучшает читабельность и понятность кода.
Существует немало руководств по стилю. Вот 2 из них, которыми в мире JavaScript пользуются чаще всего:
Вы вполне можете выбрать любое из них или придумать собственные правила. Самое главное — последовательно использовать одни и те же правила при работе над неким проектом. При этом, если, например, вы придерживаетесь одного набора правил, а в существующем проекте, над которым вам нужно поработать, используются собственные правила, нужно придерживаться правил проекта.
Форматирование кода можно выполнять вручную, а можно воспользоваться средствами автоматизации этого процесса. На самом деле, форматирование JS-кода и его проверка до запуска — это отдельная большая тема. Вот одна из наших публикаций, посвящённая соответствующим инструментам и особенностям их использования.
Стиль, используемый в этом руководстве
Автор этого материала, в качестве примера собственного руководства по стилю, приводит свод правил, которым он старается следовать, оформляя код. Он говорит, что в коде примеров ориентируется на самую свежую версию стандарта, доступную в современных версиях браузеров. Это означает, что для выполнения такого кода в устаревших браузерах понадобится использовать транспилятор, такой как Babel. JS-транспиляторы позволяют преобразовывать код, написанный с использованием новых возможностей языка, таким образом, чтобы его можно было бы выполнять в браузерах, не поддерживающих эти новые возможности. Транспилятор может обеспечивать поддержку возможностей языка, которые ещё не вошли в стандарт, то есть, не реализованы даже в самых современных браузерах.
Вот список правил, о которых идёт речь.
- Выравнивание. Для выравнивания блоков кода используются пробелы (2 пробела на 1 уровень выравнивания), знаки табуляции не используются.
- Точка с запятой. Точка с запятой не используется.
- Длина строки. 80 символов (если это возможно).
- Однострочные комментарии. Такие комментарии используются в коде.
- Многострочные комментарии. Эти комментарии используются для документирования кода.
- Неиспользуемый код. Неиспользуемый код не остаётся в программе в закомментированном виде на тот случай, если он понадобится позже. Такой код, если он всё же понадобится, можно будет найти в системе контроля версий, если она используется, или в чём-то вроде заметок программиста, предназначенных для хранения подобного кода.
- Правила комментирования. Не нужно комментировать очевидные вещи, добавлять в код комментарии, которые не помогают разобраться в его сути. Если код объясняет себя сам благодаря хорошо подобранным именам функций и переменных и JSDoc-описаниям функций, дополнительные комментарии в этот код добавлять не стоит.
- Объявление переменных. Переменные всегда объявляются в явном виде для предотвращения загрязнения глобального объекта. Ключевое слово
var
не используется. Если значение переменной в ходе выполнения программы менять не планируется, её объявляют в виде константы (подобные константы нередко тоже называют «переменными») с помощью ключевого словаconst
, используя его по умолчанию — кроме тех случаев, когда менять значение переменной планируется. В таких случаях используется ключевое словоlet
. - Константы. Если некие значения в программе являются константами, их имена составляют из прописных букв. Например —
CAPS
. Для разделения частей имён, состоящих из нескольких слов, используется знак подчёркивания (_
). - Функции. Для объявления функций используется стрелочный синтаксис. Обычные объявления функций применяются только в особых случаях. В частности, в методах объектов или в конструкторах. Делается это из-за особенностей ключевого слова
this
. Функции нужно объявлять с использованием ключевого словаconst
, и, если это возможно, надо явно возвращать из них результаты их работы. Не возбраняется использование вложенных функций для того, чтобы скрыть от основного кода некие вспомогательные механизмы.
Вот пример пары простых стрелочных функций:
const test = (a, b) => a + b
const another = a => a + 2
- Именование сущностей. Имена функций, переменных и методов объектов всегда начинаются со строчной буквы, имена, состоящие из нескольких слов, записываются с использованием верблюжьего стиля (выглядят такие имена как
camelCase
). С прописной буквы начинаются только имена функций-конструкторов и классов. Если вы используете некий фреймворк, предъявляющий особые требования к именованию сущностей — пользуйтесь предписываемыми им правилами. Имена файлов должны состоять из строчных букв, отдельные слова в именах разделяются тире (-
). - Правила построения и форматирования выражений.
if. Вот несколько способов записи условного оператора if
:
if (condition) {
statements
}
if (condition) {
statements
} else {
statements
}
if (condition) {
statements
} else if (condition) {
statements
} else {
statements
}
for. Для организации циклов используется либо стандартная конструкция for
, пример которой приведён ниже, либо цикл for of
. Циклов for in
следует избегать — за исключением тех случаев, когда они используются вместе с конструкцией .hasOwnProperty()
. Вот схема цикла for
:
for (initialization; condition; update) {
statements
}
while. Вот схематичный пример цикла while
:
while (condition) {
statements
}
do. Вот структура цикла do
:
do {
statements
} while (condition);
switch. Ниже показана схема условного оператора switch
:
switch (expression) {
case expression:
statements
default:
statements
}
try. Вот несколько вариантов оформления конструкции try-catch
. Первый пример показывает эту конструкцию без блока finally
, второй — с таким блоком.
try {
statements
} catch (variable) {
statements
}
try {
statements
} catch (variable) {
statements
} finally {
statements
}
- Пробелы. Пробелы следует использовать разумно, то есть так, чтобы они способствовали улучшению читабельности кода. Так, пробелы ставят после ключевых слов, за которыми следует открывающая круглая скобка, ими обрамляют операторы, применяемые к двум операндам (
+
,-
,/
,*
,&&
и другие). Пробелы используют внутри циклаfor
, после каждой точки с запятой, для отделения друг от друга частей заголовка цикла. Пробел ставится после запятой. - Пустые строки. Пустыми строками выделяют блоки кода, содержащие логически связанные друг с другом операции.
- Кавычки. При работе со строками используются одинарные кавычки (
'
), а не двойные ("
). Двойные кавычки обычно встречаются в HTML-атрибутах, поэтому использование одинарных кавычек помогает избежать проблем при работе с HTML-строками. Если со строками нужно выполнять некие операции, подразумевающие, например, их конкатенацию, следует пользоваться шаблонными литералами, которые оформляют с помощью обратных кавычек (`
).
Лексическая структура JavaScript-кода
Поговорим о строительных блоках JavaScript-кода. В частности — об использовании кодировки Unicode, о точках с запятой, пробелах, о чувствительности языка к регистру символов, о комментариях, о литералах, об идентификаторах и о зарезервированных словах.
▍Unicode
JavaScript-код представляется с использованием кодировки Unicode. Это, в частности, означает, что в коде, в качестве имён переменных, можно использовать, скажем, символы смайликов. Делать так, конечно же, не рекомендуется. Важно здесь то, что имена идентификаторов, с учётом некоторых правил, могут быть записаны на любом языке, например — на японском или на китайском.
▍Точка с запятой
Синтаксис JavaScript похож на синтаксис C. Вы можете встретить множество проектов, в которых, в конце каждой строки, находится точка с запятой. Однако точки с запятой в конце строк в JavaScript необязательны. В подавляющем большинстве случаев без точки с запятой можно обойтись. Разработчики, которые, до JS, пользовались языками, в которых точка с запятой не применяется, стремятся избегать их и в JavaScript.
Если вы, при написании кода, не используете странных конструкций, или не начинаете строку с круглой или квадратной скобки, то вы, в 99.9% случаев, не допустите ошибку (если что — вас о возможной ошибке может предупредить линтер). К «странным конструкциям», например, можно отнести такую:
return
variable
Использовать ли точку с запятой, или нет — это личное дело каждого программиста. Автор этого руководства, например, говорит, что решил не использовать точки с запятой там, где они не нужны, в результате в примерах, приведённых здесь, они встречаются крайне редко.
▍Пробелы
JavaScript не обращает внимания на пробелы. Конечно, в определённых ситуациях отсутствие пробела приведёт к ошибке (равно как и неуместный пробел там, где его быть не должно), но очень часто между отсутствием пробела в некоем месте программы и наличием одного или нескольких пробелов нет никакой разницы. Похожее утверждение справедливо не только для пробелов, но и для знаков перевода строки, и для знаков табуляции. Особенно хорошо это заметно, например, на минифицированном коде. Взгляните, например, во что превращается код, обработанный с помощью Closure Compiler.
В целом же надо отметить, что, форматируя код программы, лучше не впадать в крайности, придерживаясь некоего свода правил.
▍Чувствительность к регистру
JavaScript — регистрозависимый язык. Это означает, что он различает, например, имена переменных something
и Something
. То же самое касается любых идентификаторов.
▍Комментарии
В JavaScript можно использовать два типа комментариев. Первый тип — однострочные комментарии:
// Это комментарий
Они, как следует из названия, располагаются в одной строке. Комментарием считается всё, что идёт за символами //
.
Второй тип — многострочные комментарии:
/*
Многострочный
комментарий
*/
Тут комментарием считается всё, что находится между комбинацией символов /*
и */
.
▍Литералы и идентификаторы
Литералом называется некое значение, записанное в исходном коде программы. Например — это может быть строка, число, логическое значение, или более сложная структура — объектный литерал (позволяет создавать объекты, оформляется фигурными скобками) или литерал массива (позволяет создавать массивы, оформляется с помощью квадратных скобок). Вот несколько примеров:
5
'Test'
true
['a', 'b']
{color: 'red', shape: 'Rectangle'}
Особой пользы от запуска программы, в которой встречаются подобные конструкции, не будет. Для того чтобы работать с литералами в программах, их сначала присваивают переменным или передают функциям.
Идентификатором называется последовательность символов, которая может быть использована для идентификации переменной, функции, объекта. Она может начинаться с буквы, знака доллара ($
) или со знака подчёркивания (_
), может содержать цифры, и, если нужно, символы Unicode вроде смайликов (хотя, как уже было сказано, лучше так не делать). Вот несколько примеров идентификаторов:
Test
test
TEST
_test
Test1
$test
Знак доллара обычно используется при создании идентификаторов, хранящих ссылки на элементы DOM.
▍Зарезервированные слова
Ниже приведён список слов, которые зарезервированы языком. Использовать их в качестве идентификаторов нельзя.
break
do
instanceof
typeof
case
else
new
var
catch
finally
return
void
continue
for
switch
while
debugger
function
this
with
default
if
throw
delete
in
try
class
enum
extends
super
const
export
import
implements
let
private
public
interface
package
protected
static
yield
Итоги
Сегодня мы обсудили стиль и структуру программ, написанных на JavaScript. В следующий раз поговорим о переменных, о типах данных, о выражениях и об объектах.
Уважаемые читатели! Каким руководством по стилю JavaScript вы пользуетесь?
Автор: ru_vds