Есть старое наблюдение, что лучшие писатели иногда пренебрегают правилами риторики. Однако, когда они это делают, читатель обычно находит в тексте какие-то компенсирующие достоинства, появившиеся в результате такого нарушения. Пока кто-то не уверен, что он сможет сделать то же самое, ему, вероятно, лучше всего следовать правилам. —Вильям Странг, Элвин Б. Уайт. Элементы Стиля
Данный текст представляет собой набор рекоммендаций по использованию языка программирования JavaScript. На его написание меня вдохновил документ под названием Code Conventions for the Java Programming Language, изданный корпорацией Sun. Разумеется, это руководство сильно отличается от вышеназванного документа поскольку JavaScript — это не Java.
В долгосрочной перспективе ценность программы для организации напрямую зависит от качества её кода. Ведь за весь период жизни этой программы её исходный код будет неоднократно читаться и модифицироваться, а код с ясной структурой и характеристиками имеет гораздо меньшую вероятность сломаться при внесении в него изменений.
Нижеприведенные правила также помогут уменьшить уязвимость ваших программ.
Весь код, который мы пишем на JavaScript, открыт для просмотра. А потому он всегда должен быть соответствующего качества.
Это же касается и его опрятности.
Файлы с кодом на JavaScript должны иметь расширение .js.
Не вставляйте код на JavaScript в HTML, кроме случаев, когда он используется исключительно в этом месте и только один раз. Код, вставленный в HTML, увеличивает размер страницы, ограничивая при этом возможность его минификации и сжатия.
Вставляйте теги <script> как можно дальше
в конец страницы. Это уменьшает эффект от того, что эти теги
блокируют процесс последующей загрузки страницы. Необходимости в
использовании аттрибутов language
и type нет, поскольку тип MIME определяет сервер, а
не клиент.
Для оступов используйте четыре пробела. Не используйте символы табуляции, так как (на момент написания статьи, в XXI веке) до сих пор нет единого стандарта, определяющего ширину отступа. Пробелы увеличивают размер файла, однако эта проблема легко решается с помощью минификации кода.
Избегайте строк длиннее 80 символов. В случаях, когда инструкция не умещается в одну строку, её нужно разбить на несколько строк. Разбивать инструкцию стоит после оператора, желательно после запятой. Это уменьшит риск того, что при простом копировании кода в конец строки будет ошибочно вставлена точка с запятой. Вторая часть разделенной инструкции должна иметь отступ в восемь пробелов.
Оставляйте побольше комментариев. Комментарии должны помогать понимать программу, кратко отмечая наиболее значимые детали или предоставляя укрупненную картину происходящего. Иногда в комментариях можно и пошутить, а вот ругаться не стоит. Никто этого не оценит.
Каждый раз, изменив код, убедитесь в том, что комментарии ему соответствуют. Комментарий, противоречащий коду, сильно сбивает читателя с толку.
Не пишите об очевидном. В комментариях должна содержаться информация, не вытекающая из кода. Не тратьте время на комментарии вроде этого:
i = 0; // Установить i в ноль
Старайтесь использовать однострочные комментарии, оставляя многострочные для формальной документации и временного комментирования кусков кода.
Объявляйте все переменные до момента их первого использования. Это не обязательное правило языка JavaScript, однако код, следующий ему, как правило, более удобочитаем. Также предварительное объявление переменных может помочь в обнаружении необъявленных переменных, которые могут ошибочно стать неявными глобальными.
Начинайте функцию с объявления переменных. Каждое объявление желательно выделять в отдельную строку и снабжать комментарием. Все объявления должны быть отсортированны в алфавитном порядке.
var currentEntry; // текущая ячейка таблицы
var level; // уровень отступа
var size; // размер таблицы
В JavaScript нет блочной области видимости, так что объявление переменных внутри блоков может запутать программистов, пришедших с других С-подобных языков. Поэтому все объявления стоит помещать в начало функции.
Сведите использование глобальных переменных к абсолютному минимуму. Никогда не используйте неявные глобальные переменные.
Объявляйте все функции до момента их первого использования. Объявление локальных функций должно следовать сразу за объявлением переменных. Это помогает понять, какие функции и переменные используются в данной области видимости.
Не разделяйте пробелом имя функции и открывающую круглую скобку. Используйте один пробел между закрывающей круглой и открывающей фигурной скобками. Тело функции должно иметь отступ в четыре пробела относительно строки, содержащей её объявление. А вот закрывающая фигурная скобка должна быть с ней (строкой объявления) на одном уровне.
function outer(c, d) {
var e = c * d;
function inner(a, b) {
return (e * a) + b;
}
return inner(0, 1);
}
Это правило отлично работает именно в JavaScript, поскольку здесь можно вставлять функции и объекты в любое место, где разрешается использование выражения. Это делает код более читаемым при использовании вложенных, анонимных функций и сложных структур данных.
function getElementsByClassName(className) {
var results = [];
walkTheDOM(document.body, function (node) {
var a; // список классов
var c = node.className; // класс элемента
var i; // счетчик
// Если у элемента установлен аттрибут класса, разбиваем его
// на отдельные имена. Если хотя бы одно из них совпадает с
// нужным, добавляем текущий элемент к результату.
if (c) {
a = c.split(' ');
for (i = 0; i < a.length; i += 1) {
if (a[i] === className) {
results.push(node);
break;
}
}
}
});
return results;
}
Если функция анонимна, разделяйте ключевое слово function и
открывающую круглую скобку одним пробелом. Без разделения может
ошибочно показаться, что вы вызываете функцию с именем function.
div.onclick = function (e) {
return false;
};
that = {
method: function () {
return this.datum;
},
datum: 0
};
Сведите использование глобальных функций к абсолютному минимуму. Если функция вызывается сразу же, при объявлении, то вся конструкция должна быть заключена в круглые скобки. Это дает понять, что выражение возвращает результат работы функции, а не саму функцию.
var collection = (function () {
var keys = [], values = [];
return {
get: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
return value[at];
}
},
set: function (key, value) {
var at = keys.indexOf(key);
if (at < 0) {
at = keys.length;
}
keys[at] = key;
value[at] = value;
},
remove: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
keys.splice(at, 1);
value.splice(at, 1);
}
}
};
}());
Имена должны быть составлены из 26 заглавных и строчных латинских букв (A-Z, a-z), 10 цифр (0-9) и символа подчеркивания (_). Избегайте использования международных символов поскольку у читателей вашего кода могут возникнуть проблемы с понимаем или даже отображением этих символов. Не используйте символы доллара ($) и обратного слеша (\).
Не используйте символ подчеркивания в качестве первого символа в названии переменных и свойств. Иногда с помощью символа подчеркивания программист пытается указать на то, что переменная должна быть приватной. Однако, в JavaScript эта конструкция не выполняет такой функции. Если вам нужно сделать переменную приватной, используйте соответствующие конструкции. Избегайте стиля, который демонстрирует вашу некомпетентность.
Большинство переменных и функций должны начинаться со строчной буквы.
А конструкторы, которые используются вместе
с ключевым
словом new, должны начинаться с заглавной
буквы. Помните, что JavaScript не выводит никаких ошибок или
предупреждений в случае, если вы забыли new, что
может привести к сложноуловимым багам. Посему правило об
использовании заглавной буквы в начале конструкторов это всё,
что у нас есть для их предотвращения.
Набирайте имена глобальных переменных в верхнем регистре. (В JavaScript нет ни макросов, ни констант. Нет никакого смысла в использовании верхнего регистра для обозначения свойств языка, которые он не поддерживает)
Простые инструкции
Строка должна содержать максимум одну инструкцию. В конце любой простой инструкции должна стоять точка с запятой. Инструкция, которая присваивает функцию или же объект, также должна оканчиваться точкой с запятой.
JavaScript позволяет использовать любое выражение в качестве инструкции. Такой подход может привести к труднонаходимым ошибкам, особенно при ошибочном использовании точки с запятой. Используйте выражения в качестве инструкций только для присваивания и вызова.
Составные инструкции
Составные инструкции — это инструкции, содержащие в себе набор простых инструкций, заключенные в фигурные скобки.
Есть несколько простых правил, которых стоит придерживаться:
if и
for. Такой подход позволяет избегать багов при добавлении
новых инструкций.Метки
Использование меток не обязательно. Используйте метки только
с
инструкциями while, do, for
и switch.
return
Используя инструкцию return, не обрамляйте возвращаемое
значение в круглые скобки. Кроме того, помещяйте значение на
одну строку с ключевым словом, чтобы избежать ошибочной вставки
точки с запятой.
if
Условные конструкции должны иметь следующую структуру:
if (condition) {
statements
}
if (condition) {
statements
} else {
statements
}
if (condition) {
statements
} else if (condition) {
statements
} else {
statements
}
for
Циклы for должны иметь следующую структуру:
for (initialization; condition; update) {
statements
}
for (variable in object) {
if (filter) {
statements
}
}
Используйте первый вариант для массивов и других циклов с предопределенным количеством итераций.
Используйте второй вариант для итерации по свойствам
объектов. Помните, что члены объекта, добавленные в его
прототип, также будут видны в for..in. Поэтому всегда проверяйте
полученное свойство с помощью hasOwnProperty.
for (variable in object) {
if (object.hasOwnProperty(variable)) {
statements
}
}
while
Циклы while должны иметь следующую структуру:
while (condition) {
statements
}
do
Циклы do должны иметь следующую структуру:
do {
statements
} while (condition);
В отличие от всех остальных составных инструкций, циклы do
должны всегда оканчиваться точкой с запятой.
switch
switch должен иметь следующую структуру:
switch (expression) {
case expression:
statements
default:
statements
}
Каждое выражение case должно быть выровнено по первой строке инструкции во избежании чрезмерных отступов.
Каждая группа выражений, кроме default, должна оканчиваться
на break, return или throw. Никогда не «проваливайтесь» в
следующую группу.
try/catch
Конструкции try/catch должны иметь следующую структуру:
try {
statements
} catch (variable) {
statements
}
try {
statements
} catch (variable) {
statements
} finally {
statements
}
continue
Избегайте использования continue поскольку оно ухудшает
удобочитаемость программы.
with
Не
используйте конструкцию with.
Пустые строки и пробелы
Пустые строки улучшают удобочитаемость кода, визуально выделяя отдельные блоки кода.
Используйте пробелы в следующих случаях:
while (true) {
typeof).
for.
{} и []
Используйте {} вместо new Object()
и [] вместо new Array().
Если ключами являются порядковые номера, используйте массивы. В любом другом случае используйте объекты.
, (оператор запятой)
Избегайте использования запятой везде кроме цикла for. (Это
не относится к использованию запятой при объявлении объектов,
массивов, переменных и параметров)
Блочная область видимости
В JavaScript у блоков нет области видимости. Она есть только у функций. Не используйте блоки за пределами составных инструкций.
Выражения присваивания
Не присваивайте значения внутри условных частей for и if.
Корректна ли следующая строка?
if (a = b) { ... }
Или же подразумевалось следующее?
if (a == b) { ... }
Операторы === и !==
Почти всегда лучше использовать ===
и !==, поскольку == и !==
выполняют приведение типов.
Плюсы и минусы
Не используйте ++ сразу за + поскольку это может ввести
читателя в заблуждение. Разделяйте их скобками.
// плохо
total = subtotal + +myInput.value;
// лучше (+ + не может быть прочитано, как ++)
total = subtotal + (+myInput.value);
Не используйте eval
Функция eval — самая неправильно используемая функция в этом
языке. Избегайте её.
Помните, что её можно вызвать неявно и никогда не передавайте
строки в setTimeout и setInterval, а также никогда не
используйте конструктор Function.
Спасибо Камиле за помощь в редактировании этого перевода.
© 2010 Антон Ковалёв