Принятый стиль основан на Lua code conventions и довольно сильно отличается от принятых в Javascript мире. Приоритеты:
- Читаемость кода (в том числе единообразие).
- Уменьшение вероятности возникновения ошибок.
- Минимизация числа изменённых строк с точки зрения системы контроля версий при модификации кода.
- Производительность кода.
Фигурные скобки ставятся на следующей строке и выравниваются по вертикали. Блок внутри фигурных скобок отбивается единичным отступом.
function foo()
{
//Do something
}
if (price > 0)
{
//Positive
}
else
{
//Negative
}Фигурные скобки ставятся всегда!
Неправильная запись:
if (price > 0)
foo();
for (var i=0; i<10; i++)
foo(i);Правильная запись:
if (price > 0)
{
foo();
}
for (var i=0; i<10; i++)
{
foo(i);
}Тело if, else, while, switch, try и catch обязательно обрамляется фигурными скобками.
Максимальная длина строки — 80 символов.
Единичный отступ оформляется в 2 пробела. Использование табов запрещено.
Бинарные операторы отбиваются с обеих сторон пробелом. Унарные операторы пишутся слитно с переменной. Тернарный оператор отбивается пробелами. Символы ;, . и , пишутся слитно с предшествующим текстом.
var a = 1 + 2,
b = a++,
c = a > 0 ? 'yes' : 'no';После имени функции пробел не ставится.
После ключевых слов if, while, switch и catch ставится пробел.
if (condition)
{
//do something
}В конце строк обязательно ставим ';'
Пример:
var a = 10;
if (condition)
{
foo();
}
for (var i=0; i<10; i++)
{
foo(i);
}А так же в конце строки не должно быть пробельных символов.
Допустимы только unix line endings (\n).
По ряду причин, связанных с неявным приведением типов, == и != лучше не использовать.
Использовать только явное сравнение вида '!==' и '==='
Не используем !НИ В КОЕМ СЛУЧАЕ! Только преобразуем в код вида.
var a = b ? true : false;Комментарии отбиваются тем же отступом, что и блок, который они комментируют. Для описание интерфейса функции используются многострочные комментарии перед объявлением функции.
Eсли после '//' идет текст, то должен быть пробел, в других случаях (отбивка) - не нужно.
//------------------- sample ----------------------
/*
* Some really useful helper
*/
function help()
{
// Let's rock
//TODO: some todo
//NOTE: some note
//HACK: very bad :( - write clean code
}Никакой "венгерской нотации".
Константы именуются ЗАГЛАВНЫМИ_БУКВАМИ.
Обычные переменные, имена функций и проч. — через_подчёркивание, без заглавных букв.
Имя переменной, обычно, существительное.
Имя переменной, содержащей объект должно содержать название этого объекта
Имя переменной (таблицы), содержащей в себе коллекцию объектов обычно содержит существительное во множественном числе (foos — коллекция объектов foo).
Имя булевой переменной, обычно, is_* (are_, has_ и проч. формы to be), have_, need_, should_, must_, in_, not_ и т.п.
Количество объектов: num_*.
Имя функции должно заключать в себе глагол либо заканчиваться на существительное с окончанием -er (чаще всего когда подразумевается "функтор"), кроме специальных случаев и декларативного кода.
Не стоит без нужды раздувать публичный контракт объектов. Имена приватных функций и переменных должны заканчиваться символом подчеркивания.
O = new function()
{
var private_variable_;
function private_function_()
{
//Some privacy here
}
this.public_function()
{
}
}Модификация публичного контракта извне недопустима, поскольку сильно затрудняет читаемость кода.
Интерфейс и особенности реализации класса должны быть понятны из беглого обзора кода, без вчитывания в то, что там делается внутри конкретных методов. Все переменные должны быть объявлены явно до первого использования. Примерный порядок объявлений:
O = new function()
{
//private variables
//public variables
//private functions
//public functions
}Нежелательно создавать функции, которые делают разные вещи в зависимости от параметра boolean. Это затрудняет читаемость потому что глядя на вызов невозможно сказать что эта функция делает. Желательно разбивать такие функции на две:
//function remove(archive)
function delete()
function archive()Следует избегать null при инициализации переменных. Если значение не определено, нужно использовать undefined.
Для того чтобы показать что объект не инициализирован можно присвоить false переменной, в которой должен храниться объект:
var reader = false;
//...
if (reader)
{
read.do_read();
}Все внешние скрипты необходимо размещать в сервисах проекта и подключать оттуда.
Путь по которому сохраняется скрипт должен выглядеть так: js/lib/<name>/<version>/<fullfilename>.js.
Рядом неободимо положить файл VERSION.TXT. В нем указывается версия скрипта и откуда он загружен.
Пример:
Скрипт: /js/lib/jquery/1.6.2/jquery-1.6.2.min.js
VERSION.TXT: version: 1.6.2 downloaded from http://code.jquery.com/jquery-1.6.2.min.js
Для динамически подключаемых скриптов не допускается прямое использование document.write(). Вместо этого необходимо использовать соответствующие обертки от jQuery/ExtJS и аналогов.