Skip to content

Signaltec/sjsg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sjsg / Signaltech Javascript Style Guide

Code Climate

Содержание

  1. Общие моменты
  2. Отступы
  3. Длина строки
  4. Комментарии
  5. Имена
  6. Объявление переменных
  7. Объявление функций
  8. Инструкции, операторы и выражения
  1. Строки
  2. Массивы
  3. Объекты
  4. И ещё...
  5. Линтеры JSHint/JSCS

Общие моменты

  • Используйте по-возможности краткие формы;
  • {} — вместо new Object();
  • [] — вместо new Array();
  • Используйте инкремент i++ и декремент i--;
  • Используйте точное сравнение без приведения типов: a === b и a !== b;
  • Допускается приведение типа при проверке на undefined, null или пустую строку'' через !varName;
  • Для приведения к булевому типу используйте b = Boolean(a) вместо двойного отрицания b = !!a;
  • Для приведения к числу используйте краткую запись b = +a, также можно использовать b = parseInt(a, 10), но не забываете о радиксе: parseInt(arg, radix).
var o = {};
var a = [];

// явное приведение типов
i = ParseInt(a[1], 10);
b = Boolean(a[1]);
s = (i + b).toString();

// неявное приведение типов
i = +a[1];
b = !!a[1];
s = '' + i + b;

// тернарный оператор
result = (expression) ? operand1 : operand2;
или
result = expression ? operand1 : operand2;
  • Используйте запятые после, а не перед декларацией:
Плохо
var iAm = {
    firstName:  'Ildar'
  , lastName:   'Gal'
  , age:        36
};
Хорошо
var iAm = {
    firstName: 'Ildar',
    lastName: 'Gal',
    age: 36
};

Отступы

Используйте для отступов двойной пробел. Отсутствие стандарта по ширине символа табуляции приводит к тому, что код выглядит по разному в различных редакторах и IDE.

В конце файлов оставляйте пустую строку.

(function() {
←←...
})();

Длина строки

Длина строки не должна превышать 100 символов.

Комментарии

  • Используйте /* ... */ для многострочных и // ... для однострочных комментариев;
  • Для описания методов и свойств/переменных используется формат jsDoc:
/**
 * Описание метода/переменной/свойства
 * @param {type} propName описание аргумента
 */
  • Не пишите инлайновые комментарии;
  • Отбивайте комментарии пустой строкой сверху.
Плохо
var true = false,   // наебал
    a = 1;          // умный комментарий про переменную

function do(what) {
  var a = 1;
  // blah-blah
  // foo
  // bar
  var b = what || '';

  return b;
}
Хорошо
// Наебал
var true = false;

// умный комментарий
var a = 1;

/**
 * @param {string|undefined} what Строка, которая ест коров
 * @return {string}
 */
function do(what) {
  /*
    blah-blah
    foo
    bar
  */
  var b = what || '';

  return b;
}

Имена

В именах можно использовать только буквы латинского алфавита, цифры и символ подчеркивания ([A-Za-z0-9_]).

  • camelCase — для имен переменных, публичных методов и свойств;
  • _privateVar (с ведущим подчеркиванием _) — для приватных свойств;
  • UPPER_CASE — для констант;
  • PascalCase — для классов, имен конструкторов, namespace'ов;

В именах переменных и функций нельзя использовать зарезервированные слова: var, array, object, null, arguments, call, apply, case, default, ...

Имя переменных и функций должно отражать их смысл. Имя функция должно выражать действие. Если после недолгого размышления вы решили назвать переменную r_chkbx — подумайте еще.

Объявление переменных

  • Не используйте глобальные переменные;
  • Переменные должны быть объявлены cверху;
  • Каждая переменная должна быть объявлена на новой строке с индивидуальным var;
  • Переменные желательно группировать по смыслу, а затем по алфавиту;
  • Неинициализированные переменные объявляйте последними;
  • Не используйте имена, которые уже определены во внешней области видимости.
Плохо
z = 0;                          // переменная объявляется ниже как локальная

var x,y;                        // один var на несколько переменных
var uselessVar = 'useless text' // инициализированные переменные должны стоять в начале

function square(x) {            // 'x' уже определена во внешнем скоупе
  return x*x;
}

var label = 'Coding is cool!';
var z;                          // по смыслу эта переменная должна стоять рядом с 'x' и 'y'
Хорошо
var label = 'Coding is cool!';
var uselessVar = 'useless text';
var x;
var y;
var z;

function square(arg) {
  return arg * arg;
}

Объявление функций

  • Объявляйте функции до первого использования, в начале блока, но после объявления переменных;
  • Не декларируйте функции внутри блоков if, for и т. д.;
  • Между именем функции и открывающей скобкой не должно быть пробела;
  • Между закрывающей скобкой и открывающей фигурной скобкой должен быть пробел;
  • Блок тела функции должен открываться на одной строке с именем функции;
  • Для изоляции и замыканий используйте немедленно-выполняемый функтор (IIFE on MDN).
Плохо
function doSomethingUseful (){
  // here is no nothing useful in real
}

function anotherFunc()
{
  // body
}

if (true) {
  function good() { ... }
}

/**
 * Comment
 */

function a() {
  
}
function b() {
  
}
Хорошо
function doSomethingUseful() {
  // here is no nothing useful in real
}

function a() {
  
}

/**
 * Comment 
 */
function b() {
  
}

Инструкции, операторы и выражения

Простые

Размещайте каждую инструкцию на новой строке. Все инструкции кроме блочных завершаются символом ;.

Ребята, давайте жить дружно и не забывать ставить точку с запятой!

Плохо
var i=0; i=i+1;return i

if (true) {
  
};
Хорошо
var i = 0;
++i;
return i;

function a() {
  
}

var functionVariable = function() {
  
};

Блочные

  • Блоки инструкций заключаются в фигурные скобки { и };
  • Открывающая скобка завершает строку и не переносится на новую;
  • Закрывающая скобка, напротив, переносится на следующую строку, кроме случаев с однострочными блоками;
  • Используйте блок даже для одиночного выражения;
  • Разделяйте блоки пустой строкой. Если над функцией комментарий, то пустой строки не должно быть.
Плохо
/**
* Comment
* @param {object} username 
*/

var superSu = function (username)
{username.evilmode = true}

if (true) return false;
Хорошо
/**
* Comment
* @param {object} username 
*/
var superSu = function(userName) {
  userName.godMode = true;
}
// Фильтр четных чисел
[1, 2, 3, 4].filter(function(number) {
  return !(number % 2);
});

if (true) { return false; }

return

Не заключайте в скобки возвращаемый объект и не переносите его на новую строку.

Плохо
return
  a;

return (a);

if

  • Ставьте пробел перед круглыми скобками и после них;
  • Правила оформления блока описаны в соответствующем разделе.
Плохо
if(){
  ...
}

if ()
{
  ...
} else
{ ... }
Хорошо
if (...) {
  ...
} else if (...) {
  ...
} else {
  ...
}

try

try {
  ...
} catch (...) {
  ...
} finally {
  ...
}

for

  • Не объявляйте статические переменные в теле цикла;
  • Не объявляйте функции в теле цикла.
  • При переборе объектов в конструкции for...in используйте обертку hasOwnProperty для исключения из перечисления свойств, добавленных в прототип;
Плохо
var items = [ ... ];
for(i=0;i<len; i=i+1)
{
  len = items.length;
  function do(a,b) { ... }
  do(i, items[i]);
}

for(a in b){ if(b.a<10) return false }
Хорошо
function do(i, item) {
  ...
}

for(var i = 0, len = items.length; i < len; i++) {
  do(i, item[i]);
}

for (var key in object) {
  if (object.hasOwnProperty(key)) {
    if (b.a < 10) {
      return false;
    }
  }
}

while

var n = 0;
var x = 0;

while (n < 3) {
  n++;
  x += n;
}

do

var i = 0;

do {
   i += 1;
   console.log(i);
} while (i < 5);

switch

Завершайте каждый блок кроме default оператором break или throw.

switch (...) {
  case value1:
    ...
    break;
  
  case value2: return ...;
  
  default:
    throw ...;
}

with

Никогда не используйте with.

with Statement Considered Harmful

eval

Никогда не используйте eval.

eval is Evil

Строки

  • Используйте одинарные кавычки, конкатенируйте длинные строки;
  • Для новых стандартов используйте шаблонные литералы
Плохо
var name = "Vasya";

var longStr = "Note that in the 3d example, '3d' had to be quoted. It's possible to quote the JavaScript array indexes as well (e.g., years['2'] instead of years[2]), although it's not necessary.";

var longStr = "Note that in the 3d example, '3d' had to be quoted. \
Possible to quote the JavaScript array indexes as well (e.g.,  \
years['2'] instead of years[2]), although it's not necessary. The 2 ";
Хорошо
var name = 'Vasya';

var longStr = 'Note that in the 3d example, \'3d\' had to be quoted.' +
  'Possible to quote the JavaScript array indexes as well (e.g., ' +
  'years['2'] instead of years[2]), although it\'s not necessary. The 2';

или

var longStr = `Example ${varName}, something`;

Массивы

  • При инициализации массива после последнего элемента допустима запятая;
  • Используйте методы: push, map, forEach, filter, some, every, slice.
Плохо
a[a.length] = 12;

for (i = 0; i < a.length; i++) {
  a[i] = a[i] + 1;
}

var s = '<ul>';
for (i = 0; i < a.length;i++) s+= '<li>' + a[i] '</li>';
s += '</ul>';

var b = [];
for (i = 0; i < a.length; i++) {
  if (a[i] > 0) b[i] = a[i];
}

var aCopy = [];
for (i = 0; i < a.length; i++) {
  aCopy[i] = a[i];
}
Хорошо
var a = [1,2,3,];

a.push(12);

a.forEach(function(i) {i += 1;});

var s = '<ul><li>' + items.join('</li><li>') + '</li></ul>';

var aCopy = a.slice();

var b = a.filter(function(i) { return i>0; });

// чтобы получить массив свойств
var myObj = {a: 1, b: 2, c: 3, d: 'bubble-gum', e: 5};
myObj.length = Object.keys(myObj);
var myArr = Array.prototype.slice.call(myObj);

Объекты

  • Используйте this.foo = undefined вместо delete this.foo (это быстрее работает);
  • Обращение к свойству осуществляется через obj.propertyName, а не obj['propertyName'], за исключением, когда имя свойство хранится в переменной obj[variable].
Плохо
var x = {y: 123};

delete x.y;
// или
x.y = null;
// или
x['y'] = undefined;
Хорошо
x.y = undefined;

И ещё…

  • CoffeScript — нет.
  • jQuery — нет.
  • Bootstrap — нет. Используйте вместо него sega3.
  • Сеттеры и геттеры — пока нет, ждем внедрения ES6.
    // плохо
    var name = user.getName();
    user.setName('Vasya');
    
    // хорошо
    var name = user.name();
    user.name('Vasya');
  • Object.defineProperty — да.

Линтеры JSHint/JSCS

  • Скопируйте в корень проекта конфигурационные файлы:
    • linters/signaltech.jshintrc,
    • linters/signaltech.jscsrc;
  • Переименуйте:
    • signaltech.jshintrc => .jshintrc,
    • signaltech.jscsrc => .jscsrc;
  • Установите jshint и jscs:
npm install -g jshint
npm install -g jscs
  • Запустите проверку:
# из каталога с конфигурационными файлами
jshint src/app.js
jscs src/app.js

# из другого каталога
jshint /path/to/file.js --config /path/to/jshint.config
jscs /path/to/file.js --config /path/to/jscs.config

# автоматическое исправление ошибок
jscs /path/to/file.js --config /path/to/jscs.config --fix

SublimeText

В данной инструкции мы подразумеваем, что модуль Package Control уже установлен, если нет - следуйте указаниям в документации: Package Control Installation

Для подключения линтеров в SublimeText необходимо установить фреймворк SublimeLinter.

  • Нажимаем Ctrl + Shift + P, для вызова командной консоли;
  • Запрашиваем список пакетов, набрав install package (пункт Package Control: Install Package);
  • Устанавливаем пакет с именем SublimeLinter, выбрав его в списке.

Сам по себе фреймворк не содержит линтеров, они находятся в отдельных модулях. Устанавливаем пакеты SublimeLinter-jshint и SublimeLinter-jscs указанным выше методом.

Все должно заработать. Если ошибки не начали подсвечиваться, попробуйте запустить проверку стандартным сочетанием Ctrl + k, l.

PhpStorm

TODO: Добавить инструкцию

Brackets

TODO: Добавить инструкцию


Signaltech, 2019

About

Signaltech Javascript Style Guide

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published