Для тех, кто еще не знаком с этим, Google выпускает руководство по стилю для написания JavaScript, в котором излагаются (как считает Google) лучшие стилистические приемы для написания чистого, понятного кода.

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

У Google и Airbnb есть два самых популярных руководства по стилю. Я определенно рекомендую вам проверить оба из них, если вы много времени уделяете написанию JS.

Ниже приведены тринадцать, на мой взгляд, наиболее интересных и актуальных правил из Руководства по стилю JS от Google.

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

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

Используйте пробелы, а не табуляции

Помимо последовательности терминатора строки, символ горизонтального пробела 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 (т.е. ключевые слова export и import), поскольку их семантика еще не окончательно определена. Обратите внимание, что эта политика будет пересмотрена, как только семантика станет полностью стандартной.

// 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 Style. Даже не требуется поддерживать горизонтальное выравнивание в тех местах, где оно уже использовалось.

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

// bad
{
  tiny:   42,  
  longer: 435, 
};
// good
{
  tiny: 42, 
  longer: 435,
};

Больше не используйте var

Объявите все локальные переменные с помощью const или let. По умолчанию используйте const, если не требуется переназначение переменной. Ключевое слово var использовать нельзя.

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

// bad
var example = 42;
// good
let example = 42;

Стрелочные функции предпочтительны

Стрелочные функции обеспечивают краткий синтаксис и устраняют ряд проблем с this. Предпочитайте стрелочные функции ключевому слову function, особенно для вложенных функций

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

// 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}?`;
}

Не используйте продолжение строки для длинных строк

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

Интересно, что это правило, по которому Google и Airbnb расходятся во мнениях (вот спецификация 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 loop»

В ES6 в языке теперь есть три разных типа for циклов. Можно использовать все, хотя по возможности предпочтительнее использовать _39 _-_ 40_ петель.

Это странно, если вы спросите меня, но я подумал, что включу его, потому что довольно интересно, что Google объявляет предпочтительный тип цикла for.

Мне всегда казалось, что 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

Константы должны быть названы в ALL_UPPERCASE, разделенные подчеркиванием.

В именах констант используется CONSTANT_CASE: все буквы в верхнем регистре, слова разделены подчеркиванием.

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

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

// 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 - лишь один из многих технологических гигантов, и это всего лишь рекомендации.

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

Вы можете следовать этим правилам, если хотите следовать рекомендациям по «исходному коду, совместимому с Google» - но, конечно, многие люди не согласны с этим, и вы можете отмахнуться от всего этого или от всего этого.

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

— — —

Спасибо за внимание! Если вы в настоящее время делаете переход к веб-разработке или разработке программного обеспечения, я напишу больше на эту тему здесь: