Для тех, кто еще не видел: Google опубликовал руководство по стилям для JavaScript, где изложены лучшие стилистические практики (по версии компании) для написания аккуратного, понятного кода.
Это не жесткий свод правил для грамотного программирования на JavaScript, а просто набор ограничений, чтобы выдерживать единую привлекательную стилистику во всех исходных файлах. Для JavaScript подобное руководство представляет особенный интерес — это очень гибкий и нетребовательный язык, который дает значительный простор для выбора.
Самые популярные руководства по стилю — те, которые предложили Google и Airbnb. Если вы много времени проводите за работой с JS, рекомендую ознакомиться с обоими. Ниже я приведу тринадцать правил из руководства Google, которые показались мне особенно интересными. Оно затрагивает все: и камни преткновения, которые вызывают больше всего споров (пробелы против табуляции, дискуссионный вопрос о том, как использовать точки с запятой), так и некоторые менее обсуждаемые моменты, которые меня удивили. Все это определенно повлияет на мои практики написания кода в будущем.
Для каждого правила я буду приводить краткое изложение требования, цитату из руководства, где оно формулируется более подробно, а также, по возможности, примеры его применения вместе с фрагментами, где оно нарушается, чтобы можно было сравнить.
За исключением символов переноса строки, пробел в ASCII (0x20) — единственный символ, который должен появляться в исходных файлах для обозначения отступа. Это подразумевает, что… табуляция не применяется для форматирования.
Позже в руководстве также уточняется, что для отступа следует ставить два пробела, а не четыре.
Каждый оператор должен оканчиваться точкой с запятой. Полагаться на автоматическое ее проставление запрещается.
Понятия не имею, чем объясняется такое сопротивление этой идее, но споры о том, нужно ли постоянно проставлять точку с запятой в JS коде, в последнее время выходят на уровень войны между сторонниками пробелов и табуляции. Google здесь занимает решительную позицию, высказываясь в пользу точек с запятой.
В данный момент не стоит использовать модули ES6 (например, для экспорта и импорта ключевых слов), так как их семантика еще не приобрела окончательный вид. Отметим, что это правило будет пересмотрено, когда семантика будет окончательно приведена к стандарту.
Эта практика допускается, но не одобряется руководством по стилям от Google. Не требуется даже поддерживать горизонтальное выравнивание там, где оно уже применено.
Горизонтальное выравнивание — это практика, при которой в код добавляется произвольное количество дополнительных пробелов с тем расчетом, чтобы определенные значения располагались непосредственно под соответствующими значениями на верхней строке.
Объявляйте все локальные переменные при помощи const или let. Сделайте const вариантом по умолчанию, кроме тех случаев, когда переменной нужно присвоить новое значение. Ключевое слово var использовать нельзя.
В примерах кода на StackOverflow и других площадках мне до сих пор попадается var. Не знаю, есть ли у этих людей аргументы в пользу такого выбора или они просто не могут расстаться со старой привычкой.
Стрелочные функции обеспечивают лаконичный синтаксис и тем самым разрешают ряд сложностей. Отдавайте предпочтение им, а не ключевым словам для функций, особенно если речь идет о вложенных функциях.
Скажу честно: мне стрелочные функции нравятся просто потому, что они смотрятся лучше и аккуратнее. Но, как выясняется, они еще и служат довольно важной цели.
Использование шаблонов, в которых строки разделяются символом `, предпочтительнее, чем сложная конкатенация строк, особенно в случаях, когда они содержат несколько строковых литералов. Шаблоны могут заключать в себе несколько строчек.
Не используйте продолжение строки (иными словами, не завершайте строку в составе строкового литерала символом бэкслэша) ни в обычных строковых литералах, ни в литералах шаблона.
Что интересно, здесь Google расходится во мнениях с Airbnb (их спецификации можно посмотреть здесь). Если Google рекомендует применять конкатенацию для длинных строк (как показано ниже), руководство по стилю от Airbnb предписывает, в общем-то, ничего не делать и просто продолжать строку столько, сколько потребуется.
С выходом версии ES6 в языке сейчас существует три разных типа циклов for. Вы можете применять их все, однако по возможности циклам for-of следует отдавать приоритет.
На мой взгляд, это весьма странный совет, но я решил все же его включить — любопытно, что Google так выделяет для себя любимый тип цикла. Я вообще всегда пребывал под впечатлением, что циклы for… in больше подходят для объектов, а циклы for… of лучше для работы с массивами. То есть мы имеем ситуацию, когда инструмент подбираешь под задачу.
Не то чтобы спецификация от Google идет вразрез с этой мыслью, но все-таки занятно знать, что у них есть конкретный фаворит, причем именно этот.
Никогда не используйте eval() или конструктор Function(...string) (исключение составляют загрузчики программ). Эти функции несут в себе потенциальную угрозу и просто не работают в средах с CSP.
У MDN на странице, посвященной eval(), даже есть особый раздел под названием «Никогда не используйте eval()!»
Названия констант прописываются в особом формате: заглавными буквами и с нижними подчеркиваниями между отдельными словами.
Если вы совершенно уверены, что переменная должна оставаться неизменной, можно подчеркнуть это, прописывая ее название заглавными буквами. Так читающему код будет сразу понятно, что переменная неприкосновенна, в каком бы фрагменте она ему ни встретилась.
Важное исключение из этого правила составляют константы в пределах функции. В их случае следует использовать верблюжий регистр.
На каждую локальную переменную отводится отдельное объявление. Объявления вида let a = 1, b = 2 не допускаются.
Стандартные строковые литералы отделяются одинарными кавычками ('), двойные (") для этой цели не употребляются.
Совет: если строка уже содержит символ одинарной кавычки, подумайте о том, чтобы использовать шаблон с обратными кавычками — это позволит избежать проблем с форматированием.
Как я говорил в начале, это не стоит считать все это непоколебимыми заповедями. Кроме Google, есть и другие IT гиганты, да и правила эти носят скорее рекомендательный характер.
Но даже с этой оговоркой, рекомендации по стилю от такой компании, как Google, у которой множество талантливых сотрудников, пишущих отличный код, вызывают немалый интерес. Вы можете придерживаться этих правил, если хотите писать «исходный код, совместимый с продуктами Google», а можете просто махнуть на них рукой.
Лично мне кажется, что спецификации Airbnb во многих отношениях привлекательнее, чем у Google. Но какую бы позицию вы не заняли по отношению к этим правилам, важно помнить одно: при работе над любым кодом в стилистике должно выдерживаться постоянство.
Это не жесткий свод правил для грамотного программирования на JavaScript, а просто набор ограничений, чтобы выдерживать единую привлекательную стилистику во всех исходных файлах. Для JavaScript подобное руководство представляет особенный интерес — это очень гибкий и нетребовательный язык, который дает значительный простор для выбора.
Самые популярные руководства по стилю — те, которые предложили Google и Airbnb. Если вы много времени проводите за работой с JS, рекомендую ознакомиться с обоими. Ниже я приведу тринадцать правил из руководства Google, которые показались мне особенно интересными. Оно затрагивает все: и камни преткновения, которые вызывают больше всего споров (пробелы против табуляции, дискуссионный вопрос о том, как использовать точки с запятой), так и некоторые менее обсуждаемые моменты, которые меня удивили. Все это определенно повлияет на мои практики написания кода в будущем.
Для каждого правила я буду приводить краткое изложение требования, цитату из руководства, где оно формулируется более подробно, а также, по возможности, примеры его применения вместе с фрагментами, где оно нарушается, чтобы можно было сравнить.
Используйте пробелы, а не табуляцию
За исключением символов переноса строки, пробел в ASCII (0x20) — единственный символ, который должен появляться в исходных файлах для обозначения отступа. Это подразумевает, что… табуляция не применяется для форматирования.
Позже в руководстве также уточняется, что для отступа следует ставить два пробела, а не четыре.
// bad
function foo() {
∙∙∙∙let name;
}
// bad
function bar() {
∙let name;
}
// good
function baz() {
∙∙let name;
}
Точки с запятой необходимы
Каждый оператор должен оканчиваться точкой с запятой. Полагаться на автоматическое ее проставление запрещается.
Понятия не имею, чем объясняется такое сопротивление этой идее, но споры о том, нужно ли постоянно проставлять точку с запятой в JS коде, в последнее время выходят на уровень войны между сторонниками пробелов и табуляции. Google здесь занимает решительную позицию, высказываясь в пользу точек с запятой.
// bad
let luke = {}
let leia = {}
[luke, leia].forEach(jedi => jedi.father = 'vader')
// good
let luke = {};
let leia = {};
[luke, leia].forEach((jedi) => {
jedi.father = 'vader';
});
Не используйте модули ES6 (пока что)
В данный момент не стоит использовать модули ES6 (например, для экспорта и импорта ключевых слов), так как их семантика еще не приобрела окончательный вид. Отметим, что это правило будет пересмотрено, когда семантика будет окончательно приведена к стандарту.
// Don't do this kind of thing yet:
//------ lib.js ------
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
Горизонтальное выравнивание не рекомендуется (хотя и не запрещается)
Эта практика допускается, но не одобряется руководством по стилям от Google. Не требуется даже поддерживать горизонтальное выравнивание там, где оно уже применено.
Горизонтальное выравнивание — это практика, при которой в код добавляется произвольное количество дополнительных пробелов с тем расчетом, чтобы определенные значения располагались непосредственно под соответствующими значениями на верхней строке.
// bad
{
tiny: 42,
longer: 435,
};
// good
{
tiny: 42,
longer: 435,
};
Не используйте больше var
Объявляйте все локальные переменные при помощи const или let. Сделайте const вариантом по умолчанию, кроме тех случаев, когда переменной нужно присвоить новое значение. Ключевое слово var использовать нельзя.
В примерах кода на StackOverflow и других площадках мне до сих пор попадается var. Не знаю, есть ли у этих людей аргументы в пользу такого выбора или они просто не могут расстаться со старой привычкой.
// bad
var example = 42;
// good
let example = 42;
Предпочтение отдается стрелочным функциям
Стрелочные функции обеспечивают лаконичный синтаксис и тем самым разрешают ряд сложностей. Отдавайте предпочтение им, а не ключевым словам для функций, особенно если речь идет о вложенных функциях.
Скажу честно: мне стрелочные функции нравятся просто потому, что они смотрятся лучше и аккуратнее. Но, как выясняется, они еще и служат довольно важной цели.
// bad
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
// good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
Используйте шаблонные строки вместо конкатенации
Использование шаблонов, в которых строки разделяются символом `, предпочтительнее, чем сложная конкатенация строк, особенно в случаях, когда они содержат несколько строковых литералов. Шаблоны могут заключать в себе несколько строчек.
// bad
function sayHi(name) {
return 'How are you, ' + name + '?';
}
// bad
function sayHi(name) {
return ['How are you, ', name, '?'].join();
}
// bad
function sayHi(name) {
return `How are you, ${ name }?`;
}
// good
function sayHi(name) {
return `How are you, ${name}?`;
}
Не используйте продолжение строки для длинных строк
Не используйте продолжение строки (иными словами, не завершайте строку в составе строкового литерала символом бэкслэша) ни в обычных строковых литералах, ни в литералах шаблона.
Что интересно, здесь Google расходится во мнениях с Airbnb (их спецификации можно посмотреть здесь). Если Google рекомендует применять конкатенацию для длинных строк (как показано ниже), руководство по стилю от Airbnb предписывает, в общем-то, ничего не делать и просто продолжать строку столько, сколько потребуется.
// bad (sorry, this doesn't show up well on mobile)
const longString = 'This is a very long string that \
far exceeds the 80 column limit. It unfortunately \
contains long stretches of spaces due to how the \
continued lines are indented.';
// good
const longString = 'This is a very long string that ' +
'far exceeds the 80 column limit. It does not contain ' +
'long stretches of spaces since the concatenated ' +
'strings are cleaner.';
for… of — оптимальная разновидность циклов for
С выходом версии ES6 в языке сейчас существует три разных типа циклов for. Вы можете применять их все, однако по возможности циклам for-of следует отдавать приоритет.
На мой взгляд, это весьма странный совет, но я решил все же его включить — любопытно, что Google так выделяет для себя любимый тип цикла. Я вообще всегда пребывал под впечатлением, что циклы for… in больше подходят для объектов, а циклы for… of лучше для работы с массивами. То есть мы имеем ситуацию, когда инструмент подбираешь под задачу.
Не то чтобы спецификация от Google идет вразрез с этой мыслью, но все-таки занятно знать, что у них есть конкретный фаворит, причем именно этот.
Не используйте eval()
Никогда не используйте eval() или конструктор Function(...string) (исключение составляют загрузчики программ). Эти функции несут в себе потенциальную угрозу и просто не работают в средах с CSP.
У MDN на странице, посвященной eval(), даже есть особый раздел под названием «Никогда не используйте eval()!»
// bad
let obj = { a: 20, b: 30 };
let propName = getPropName(); // returns "a" or "b"
eval( 'var result = obj.' + propName );
// good
let obj = { a: 20, b: 30 };
let propName = getPropName(); // returns "a" or "b"
let result = obj[ propName ]; // obj[ "a" ] is the same as obj.a
Константы должны записывать КАПСЛОКОМ и разделяться нижними подчеркиваниями
Названия констант прописываются в особом формате: заглавными буквами и с нижними подчеркиваниями между отдельными словами.
Если вы совершенно уверены, что переменная должна оставаться неизменной, можно подчеркнуть это, прописывая ее название заглавными буквами. Так читающему код будет сразу понятно, что переменная неприкосновенна, в каком бы фрагменте она ему ни встретилась.
Важное исключение из этого правила составляют константы в пределах функции. В их случае следует использовать верблюжий регистр.
// bad
const number = 5;
// good
const NUMBER = 5;
Одна переменная — одно объявление
На каждую локальную переменную отводится отдельное объявление. Объявления вида let a = 1, b = 2 не допускаются.
// bad
let a = 1, b = 2, c = 3;
// good
let a = 1;
let b = 2;
let c = 3;
Используйте одинарные кавычки, а не двойные
Стандартные строковые литералы отделяются одинарными кавычками ('), двойные (") для этой цели не употребляются.
Совет: если строка уже содержит символ одинарной кавычки, подумайте о том, чтобы использовать шаблон с обратными кавычками — это позволит избежать проблем с форматированием.
// bad
let directive = "No identification of self or mission."
// bad
let saying = 'Say it ain\u0027t so.';
// good
let directive = 'No identification of self or mission.';
// good
let saying = `Say it ain't so`;
И напоследок
Как я говорил в начале, это не стоит считать все это непоколебимыми заповедями. Кроме Google, есть и другие IT гиганты, да и правила эти носят скорее рекомендательный характер.
Но даже с этой оговоркой, рекомендации по стилю от такой компании, как Google, у которой множество талантливых сотрудников, пишущих отличный код, вызывают немалый интерес. Вы можете придерживаться этих правил, если хотите писать «исходный код, совместимый с продуктами Google», а можете просто махнуть на них рукой.
Лично мне кажется, что спецификации Airbnb во многих отношениях привлекательнее, чем у Google. Но какую бы позицию вы не заняли по отношению к этим правилам, важно помнить одно: при работе над любым кодом в стилистике должно выдерживаться постоянство.