Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

WebHero JavaScript Style Guide

В данном руководстве описаны подходы по оформлению Java Script. Данное руководство не является железным правилом для всех проектов во frontend, а только рекомендации для разработки проектов в нашей школе 🙂 На вашей работе могут быть другие правила. Все правила обсуждаются и согласовываются участниками команды и придерживаются их на протяжении разработки всего проекта.

 

Содержание

  1. Соглашение об именовании
  2. Переменные
  3. Объявление переменных
  4. Запятые
  5. Точка с запятой
  6. Блоки
  7. Объекты
  8. Массивы
  9. Деструктуризация
  10. Строки
  11. Функции
  12. Стрелочные функции
  13. Классы и конструкторы
  14. Модули
  15. Генераторы
  16. Операторы сравнения
  17. Комментарии
  18. Пробелы
  19. Преобразование и приведение типов
  20. Регулярные выражения

 

Соглашение об именовании.

 

1. Избегайте однобуквенных названий.

eslint: id-length

 

❌ не надо так 👇

function q() {
  // ...
}

 

✅ надо так 👇

function query() {
  // ...
}

 

2. Используйте camelCase для названий переменных, объектов и функций.

eslint: camelcase

 

❌ не надо так 👇

const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}

 

✅ надо так 👇

const thisIsMyObject = {};
function thisIsMyFunction() {}

 

3. Используйте PascalCase для именования конструкторов или классов.

eslint: new-cap

 

❌ не надо так 👇

function user(options) {
  this.name = options.name;
}

const bad = new user({
  name: 'nope',
});

 

✅ надо так 👇

class User {
  constructor(options) {
    this.name = options.name;
  }
}

const good = new User({
  name: 'yup',
});

 

4. Не используйте нижнее подчеркивание в начале или конце названий.

eslint: no-underscore-dangle

 

❌ не надо так 👇

let name_ = 'Max';
foo._bar();

 

✅ надо так 👇

let name = 'Max';
foo.bar();

 

Исключения:

  • разрешено использовать нижнее подчеркивание после this.

Так принято помечать псевдоприватные поля.

 

✅ надо так 👇

this._bar();
let a = this.foo_;

⬆ Вернуться к содержанию

 

Переменные.

 

1. Всегда используйте let или const для объявления переменных.

eslint: no-undef, prefer-const

 

❌ не надо так 👇

uperPower = new SuperPower();

 

✅ надо так 👇

const superPower = new SuperPower();

 

2. Не нужно неинициализированной переменной задавать значение undefined, это значение присваивается автоматически.

eslint: no-undef

 

❌ не надо так 👇

let foo = undefined;
let bar = undefined;

 

✅ надо так 👇

let foo;
let bar;

 

3. Используйте let и const для объявления каждой переменной.

eslint: one-var

 

❌ не надо так 👇

const items = getItems(),
    goSportsTeam = true,
    dragonball = 'z';

 

✅ надо так 👇

const items = getItems();
const goSportsTeam = true;
const dragonball = 'z';

 

4. Не используйте множественное присваивание. Такие конструкции создают неявные глобальные переменные.

eslint: no-multi-assign, one-var

 

❌ не надо так 👇

(function example() {
  let a = b = c = 1;
}());

console.log(a); // ошибка ReferenceError
console.log(b); // 1
console.log(c); // 1

 

✅ надо так 👇

(function example() {
  let a = 1;
  let b = a;
  let c = a;
}());

console.log(a); // ошибка ReferenceError
console.log(b); // ошибка ReferenceError
console.log(c); // ошибка ReferenceError

 

5. Не переноси строку после оператора присваивания.

eslint : operator-linebreak

  При нарушении правила max-len оборачивай присваивание в скобки.

 

❌ не надо так 👇

const foo =
  superLongLongLongLongLongLongLongLongFunctionName();


const foo
  = 'superLongLongLongLongLongLongLongLongString';

 

✅ надо так 👇

const foo = (
  superLongLongLongLongLongLongLongLongFunctionName()
);

const foo = 'superLongLongLongLongLongLongLongLongString';

 

6. Не объявляй неиспользуемые переменные.

eslint: no-unused-vars

 

❌ не надо так 👇

let x = 0;
let y = 1; // Переменная не используется

function getX() {
    return x + 1;
}

 

✅ надо так 👇

let x = 0;

function getX() {
    return x + 1;
}

⬆ Вернуться к содержанию

 

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

 

1. Если ты не переназначаешь переменную, то используй const для ее объявления. И наоборот.

eslint: prefer-const, no-const-assign

 

❌ не надо так 👇

var a = 1;
var b = 2;

var count = 1;
if (true) {
  count += 1;
}

 

✅ надо так 👇

const a = 1;
const b = 2;

let count = 1;
if (true) {
  count += 1;
}

 

2. Не используй var. Используй let и const.

eslint: no-var

 

❌ не надо так 👇

var x = "y";
var CONFIG = {};

 

✅ надо так 👇

let x = "y";
const CONFIG = {};

⬆ Вернуться к содержанию

 

Запятые.

 

1. Запятые не должны быть в начале строки.

eslint: comma-style

 

❌ не надо так 👇

const story = [
    once
  , upon
  , aTime
];

 

✅ надо так 👇

const story = [
  once,
  upon,
  aTime,
];

 

2. Ставь запятую после последнего свойства в объектах и массивах .Они делают git-diff более чистым.

eslint: comma-dangle

  git-diff без использования оконечной запятой

const hero = {
     firstName: 'Florence',
-    lastName: 'Nightingale'
+    lastName: 'Nightingale',
+    inventorOf: ['coxcomb chart', 'modern nursing']
};

git diff с использованием оконечной запятой

const hero = {
     firstName: 'Florence',
     lastName: 'Nightingale',
+    inventorOf: ['coxcomb chart', 'modern nursing'],
};

 

❌ не надо так 👇

const hero = {
  firstName: 'Dana',
  lastName: 'Scully'
};

 

✅ надо так 👇

const hero = {
  firstName: 'Dana',
  lastName: 'Scully',
};

// Но учтите, что ставить запятую после “rest” элемента нельзя
function createHero(
  firstName,
  lastName,
  inventorOf,
  ...heroArgs
) {
  // does nothing
}

⬆ Вернуться к содержанию

 

Точка с запятой.

 

1. Всегда ставьте точку с запятой в конце выражения.

eslint: semi

 

❌ не надо так 👇

// Выбросит исключение
const luke = {}
const leia = {}
[luke, leia].forEach((jedi) => jedi.father = 'vader')

// Выбросит исключение
const reaction = "No! That’s impossible!"
(async function meanwhileOnTheFalcon() {
  // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
  // ...
}())

// Вернет `undefined` вместо корректной строки так return находится один в строке и ASI автоматически вставит точку с запятой именно туда!
function foo() {
  return
    'search your feelings, you know it to be foo'
}

 

✅ надо так 👇

const luke = {};
const leia = {};
[luke, leia].forEach((jedi) => {
  jedi.father = 'vader';
});

const reaction = "No! That’s impossible!";
(async function meanwhileOnTheFalcon() {
  // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
  // ...
}());

function foo() {
  return 'search your feelings, you know it to be foo';
}

⬆ Вернуться к содержанию

 

Блоки.

 

1. Используй фигурные скобки для всех многострочных блоков.

eslint: nonblock-statement-body-position

 

❌ не надо так 👇

if (test)
  return false;

function foo() { return false; }

 

✅ надо так 👇

if (test) return false;

function bar() {
  return false;
}

 

2. При использовании конструкции if .. else располагайте else на одной строке со скобкой закрывающей блок if.

eslint: brace-style

 

❌ не надо так 👇

if (test) {
  thing1();
  thing2();
}
else {
  thing3();
}

 

✅ надо так 👇

if (test) {
  thing1();
  thing2();
} else {
  thing3();
}

 

3. Если в блоке if вы используете return, то последующее использование блока else не требуется. Условия, использующие return в обеих частях if .. else if .. могут быть разбиты на два отдельных условия.

eslint: no-else-return

 

❌ не надо так 👇

function foo() {
  if (x) {
    return x;
  } else {
    return y;
  }
}

function cats() {
  if (x) {
    return x;
  } else if (y) {
    return y;
  }
}

function dogs() {
  if (x) {
    return x;
  } else {
    if (y) {
      return y;
    }
  }
}

 

✅ надо так 👇

function foo() {
  if (x) {
    return x;
  }

  return y;
}

function cats() {
  if (x) {
    return x;
  }

  if (y) {
    return y;
  }
}

function dogs(x) {
  if (x) {
    if (z) {
      return y;
    }
  } else {
    return z;
  }
}

 

4. Не оставляй пустые блоки в рабочем коде .

eslint: no-empty

 

❌ не надо так 👇

if (foo) {
}

while (foo) {
}

switch(foo) {
}

try {
    doSomething();
} catch(ex) {

} finally {

}

 

✅ надо так 👇

if (foo) {
    // empty
}

while (foo) {
    /* empty */
}

try {
    doSomething();
} catch (ex) {
    // continue regardless of error
}

try {
    doSomething();
} finally {
    /* continue regardless of error */
}

⬆ Вернуться к содержанию

 

Объекты.

 

1. Для объявления объекта использую фигурные скобки.

eslint: no-new-object

 

❌ не надо так 👇

const item = new Object();

 

✅ надо так 👇

const item = {};

 

2. Не дублируй названия ключей в объектах.

eslint: no-dupe-keys

 

❌ не надо так 👇

var foo = {
    bar: "baz",
    bar: "qux"
};

var foo = {
    "bar": "baz",
    bar: "qux"
};

 

✅ надо так 👇

var foo = {
    bar: "baz",
    quxx: "qux"
};

 

3. Не вызывай встроенные методы Object.prototype (такие как hasOwnProperty, propertyIsEnumerable, и isPrototypeOf) у самих объектов. Вместо этого вызывай их с помощью call передавая в него объект.

eslint: no-prototype-builtins

 

Такие встроенные методы могут быть переопределены в объекте и могут работать не так, как они описаны в Object.prototype

 

❌ не надо так 👇

object.hasOwnProperty(key);

 

✅ надо так 👇

Object.prototype.hasOwnProperty.call(object, key);

// еще лучше
const has = Object.prototype.hasOwnProperty;
console.log(has.call(object, key));
/* или*/
import has from 'has';
console.log(has(object, key));

 

4. Ставь один пробел после двоеточия в массиве, но не ставь пробел до двоеточия.

eslint: key-spacing

 

❌ не надо так 👇

let obj = { "foo" : 42 };

 

✅ надо так 👇

let obj = { "foo": 42 };

 

5. Не форматируй свойства объектов так, чтобы они находились на одной линии.

eslint: key-spacing

 

❌ не надо так 👇

let obj = {
  foobar: 42,
  bat:    2 * 2
};

 

✅ надо так 👇

let obj = {
  foobar: 42,
  bat: 2 * 2
};

 

6. В многострочных объектах после открывающей фигурной скобки свойства необходимо писать с новой строки. Закрывающую фигурную скобку следует также расположить на новой строке. Если объект однострочный, фигурные скобки должны находиться на одной строке.

eslint: object-curly-newline

 

❌ не надо так 👇

let a = {foo: 1
};
let b = {
  foo: 1};
let c = {foo: 1, bar: 2
};
let d = {
  foo: 1, bar: 2};
let e = {foo: function() {
  dosomething();
}};

let {f
} = obj;
let {
  g} = obj;
let {h, i
} = obj;
let {
  j, k} = obj;
let {l = function() {
  dosomething();
}} = obj;

 

✅ надо так 👇

let a = {};
let b = {foo: 1};
let c = {
  foo: 1
};
let d = {
  foo: 1, bar: 2
};
let e = {
  foo: 1,
  bar: 2
};
let f = {foo: function() {dosomething();}};
let g = {
  foo: function() {
      dosomething();
  }
};

let {} = obj;
let {h} = obj;
let {i, j} = obj;
let {
  k, l
} = obj;
let {
  m,
  n
} = obj;
let {
  o,
  p
} = obj;
let {q = function() {dosomething();}} = obj;
let {
  r = function() {
      dosomething();
  }
} = obj;

 

7. В однострочных объектах не ставь пробел после открывающей фигурной скобки и перед закрывающей фигурной скобкой.

eslint: object-curly-spacing

 

❌ не надо так 👇

let obj = { 'foo': 'bar' };
let obj = {'foo': 'bar' };
let obj = { baz: {'foo': 'qux'}, bar};
let obj = {baz: { 'foo': 'qux'}, bar};
let {x } = y;
import { foo } from 'bar';

 

✅ надо так 👇

let obj = {'foo': 'bar'};
let obj = {'foo': {'bar': 'baz'}, 'qux': 'quxx'};
let obj = {
  'foo': 'bar'
};
let obj = {'foo': 'bar'
};
let obj = {
  'foo':'bar'};
let obj = {};
let {x} = y;
import {foo} from 'bar';

 

8. Пиши каждую пару ключ свойство с новой строки.

eslint: object-property-newline

 

❌ не надо так 👇

const obj0 = { foo: "foo", bar: "bar", baz: "baz" };

const obj1 = {
  foo: "foo", bar: "bar", baz: "baz"
};

const obj2 = {
  foo: "foo", bar: "bar",
  baz: "baz"
};

const obj3 = {
  [process.argv[3] ? "foo" : "bar"]: 0, baz: [
    1,
    2,
    4,
    8
  ]
};

 

✅ надо так 👇

const obj1 = {
  foo: "foo",
  bar: "bar",
  baz: "baz"
};


const user = process.argv[2];
const obj3 = {
  user,
  [process.argv[3] ? "foo" : "bar"]: 0,
  baz: [
    1,
    2,
    4,
    8
  ]
};

 

9. Для доступа к свойствам объекта используйте точечную запись.

eslint: dot-notation

 

❌ не надо так 👇

const luke = {
  jedi: true,
  age: 28,
};

const isJedi = luke['jedi'];

 

✅ надо так 👇

const isJedi = luke.jedi;

⬆ Вернуться к содержанию

 

Массивы.

 

1. Используй квадратные скобки [ ] для объявления массивов.

eslint: no-array-constructor

 

❌ не надо так 👇

const items = new Array();

 

✅ надо так 👇

const items = [];

 

2. Не ставь пробел после открывающей квадратной скобки и перед закрывающей квадратной скобкой.

eslint: array-bracket-spacing

 

❌ не надо так 👇

const arr = [ 'foo', 'bar' ];
const arr = ['foo', 'bar' ];
const arr = [ ['foo'], 'bar'];
const arr = [[ 'foo' ], 'bar'];
const arr = [ 'foo',
  'bar'
];
const [ x, y ] = z;
const [ x,y ] = z;
const [ x, ...y ] = z;
const [ ,,x, ] = z;

 

✅ надо так 👇

const arr = [];
const arr = ['foo', 'bar', 'baz'];
const arr = [['foo'], 'bar', 'baz'];
const arr = [
  'foo',
  'bar',
  'baz'
];
const arr = ['foo',
  'bar'
];
const arr = [
  'foo',
  'bar'];

const [x, y] = z;
const [x,y] = z;
const [x, ...y] = z;
const [,,x,] = z;

 

3. Не оставляй пусты места (“дыры”) в массивах.

eslint: no-sparse-arrays

 

❌ не надо так 👇

let items = [,];
let colors = [ "red",, "blue" ];

 

✅ надо так 👇

let items = ["red", "blue"];

// можно ставить завершающую запятую после последнего элемента 
let colors = [ "red", "blue", ];

 

4. При использовании перебирающих методов массивов в коллбэке всегда используй return для возврата результата коллбэка. Если тебе не нужно использовать результат коллбэка, используй для перебора forEach.

eslint: array-callback-return

 

❌ не надо так 👇

inbox.filter((msg) => {
  const { subject, author } = msg;
  if (subject === 'Mockingbird') {
    return author === 'Harper Lee';
  } else {
    return false;
  }
});

[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
  const flatten = acc.concat(item);
});

 

✅ надо так 👇

[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});


[1, 2, 3].map((x) => x + 1);

[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
  const flatten = acc.concat(item);
  return flatten;
});



inbox.filter((msg) => {
  const { subject, author } = msg;
  if (subject === 'Mockingbird') {
    return author === 'Harper Lee';
  }

  return false;
});

⬆ Вернуться к содержанию

 

Деструктуризация.

 

1. Используй деструктуризацию объектов и массивов при использовании нескольких свойств объекта или значений массива.

eslint: prefer-destructuring

 

Это позволит сократить код.

 

❌ не надо так 👇

function getFullName(user) {
  const firstName = user.firstName;
  const lastName = user.lastName;

  return `${firstName} ${lastName}`;
}

const arr = [1, 2, 3, 4];
const first = arr[0];
const second = arr[1];

 

✅ надо так 👇

function getFullName(user) {
  const { firstName, lastName } = user;
  return `${firstName} ${lastName}`;
}

// еще лучше
function getFullName({ firstName, lastName }) {
  return `${firstName} ${lastName}`;
}

const arr = [1, 2, 3, 4];
const [first, second] = arr;

⬆ Вернуться к содержанию

 

Строки.

 

1. Используй одинарные кавычки ' ' для строк.

eslint: quotes

 

❌ не надо так 👇

const name = "Capt. Janeway";

 

✅ надо так 👇

const name = 'Capt. Janeway';

 

2. Если в строке ты обращаешься к какой-либо переменной через ${variable} , то такая строка должна быть обернута в обратные кавычки .

eslint: no-template-curly-in-string

❌ не надо так 👇

'Hello ${name}!';
'Time: ${12 * 60 * 60 * 1000}';

 

✅ надо так 👇

`Hello ${name}!`;
`Time: ${12 * 60 * 60 * 1000}`;

templateFunction`Hello ${name}`;

 

3. Используй шаблонные строки вместо конкатенации.

eslint: prefer-template, template-curly-spacing

❌ не надо так 👇

function sayHi(name) {
  return 'How are you, ' + name + '?';
}

function sayHi(name) {
  return ['How are you, ', name, '?'].join();
}

function sayHi(name) {
  return `How are you, ${ name }?`;
}

 

✅ надо так 👇

function sayHi(name) {
  return `How are you, ${name}?`;
}

 

4. Никогда не используй функцию eval().

eslint: no-eval

❌ не надо так 👇

let obj = { x: "foo" },
  key = "x",
  value = eval("obj." + key);

 

✅ надо так 👇

let obj = { x: "foo" },
  key = "x",
  value = obj[key];

⬆ Вернуться к содержанию

 

Функции.

 

1. Используй function expressions (Функциональное Выражение) и присваивай ее переменной вместо function declarations (Объявление Функции).

Лучше: используй стрелочные функции.

eslint: func-style

 

Это позволит избежать ошибок, если функция будет вызвана до ее объявления.

 

❌ не надо так 👇

function foo() {
  // ...
}

const foo = function () {
  // ...
};

 

✅ надо так 👇

const short = function longUniqueMoreDescriptiveLexicalFoo() {
  // ...
};

//лучше
const foo = () => {};

 

2. Оборачивай в скобки немедленно вызывамые функции IIFE.

eslint: wrap-iife

 

❌ не надо так 👇

const x = function () { return { y: 1 };}(); 
const x = (function () { return { y: 1 };})(); 

 

✅ надо так 👇

const x = (function () { return { y: 1 };}())

 

3. Не объявляй функцию внутри цикла.

eslint: no-loop-func

 

❌ не надо так 👇

for (let i=10; i; i--) {
  (function() { return i; })();
}

while(i) {
  const a = function() { return i; };
  a();
}

 

✅ надо так 👇

const a = function() {};

for (let i=10; i; i--) {
  a();
}

 

4. Не используй argument для получения аргументов, вместо этого используй rest оператор.

eslint: prefer-rest-params

 

❌ не надо так 👇

function foo() {
  console.log(arguments);
}

function foo(action) {
  const args = Array.prototype.slice.call(arguments, 1);
  action.apply(null, args);
}

function foo(action) {
  const args = [].slice.call(arguments, 1);
  action.apply(null, args);
}

 

✅ надо так 👇

function foo(...args) {
    console.log(args);
}

function foo(action, ...args) {
    action.apply(null, args); 
}

 

5. Не используй new Function для создания функций.

eslint: no-new-func

 

❌ не надо так 👇

const add = new Function('a', 'b', 'return a + b');

 

✅ надо так 👇

const subtract = Function('a', 'b', 'return a - b');

 

6. Всегда ставь один пробел перед () и перед {} в функциях.

eslint: space-before-function-paren, space-before-blocks

 

❌ не надо так 👇

const f = function(){};
const g = function (){};
const h = function() {};

 

✅ надо так 👇

const x = function () {};
const y = function a() {};

 

7. Не переназначай аргументы функции.

eslint: no-param-reassign

 

❌ не надо так 👇

function foo(bar) {
  bar = 13;
}

function foo(bar) {
  bar++;
}

 

✅ надо так 👇

function foo(bar) {
  let baz = bar;
}

 

8. Не дублируй названия аргументов в функциях.

eslint: no-dupe-args

 

❌ не надо так 👇

function foo(a, b, a) {
  console.log("value of the second a:", a);
}

const bar = function (a, b, a) {
  console.log("value of the second a:", a);
};

 

✅ надо так 👇

function foo(a, b, c) {
  console.log(a, b, c);
}

const bar = function (a, b, c) {
  console.log(a, b, c);
};

⬆ Вернуться к содержанию

 

Стрелочные функции.

 

1. Используйте стрелочные функции для передачи коллбеков.

eslint: prefer-arrow-callback, arrow-spacing

 

❌ не надо так 👇

[1, 2, 3].map(function (x) {
  const y = x + 1;
  return x * y;
});

 

✅ надо так 👇

[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});

 

2. Если тело функции состоит из одной операции, то можно опустить фигурные скобки и использовать неявный return.

eslint: arrow-body-style

 

❌ не надо так 👇

[1, 2, 3].map((number) => {
  const nextNumber = number + 1;
  `A string containing the ${nextNumber}.`;
});

 

✅ надо так 👇

[1, 2, 3].map((number) => `A string containing the ${number + 1}.`);

 

3. При использовании стрелочной функции не оборачивай аргумент в скобки, если он один.

eslint: arrow-parens

 

❌ не надо так 👇

(a) => {}

 

✅ надо так 👇

a => {}
(a, b) => {}

 

4. Использование стрелочных функций совместно с операторами сравнения может запутать. Оборачивайте такие участки кода в скобки.

eslint: no-confusing-arrow

 

❌ не надо так 👇

const itemHeight = (item) => item.height <= 256 ? item.largeSize : item.smallSize;
const itemHeight = (item) => item.height >= 256 ? item.largeSize : item.smallSize;

 

✅ надо так 👇

const itemHeight = (item) => (item.height <= 256 ? item.largeSize : item.smallSize);

const itemHeight = (item) => {
  const { height, largeSize, smallSize } = item;
  return height <= 256 ? largeSize : smallSize;
};

 

5. Не делай переносы строк сразу после стрелочной функции.

eslint: implicit-arrow-linebreak

 

❌ не надо так 👇

foo =>
  bar;

foo =>
  (bar);

 

✅ надо так 👇

foo => bar;
foo => (bar);
foo => (
   bar
)

⬆ Вернуться к содержанию

 

Классы и конструкторы.

 

1. Называй функции-конструкторы с большой буквы.

eslint: new-cap

 

❌ не надо так 👇

const colleague = new person();
const friend = new person.acquaintance();

 

✅ надо так 👇

const colleague = new Person();
const friend = new person.Acquaintance();

 

2. Не пиши пустой конструктор в классах. Классы имеют конструктор по умолчанию.

eslint: no-useless-constructor

 

❌ не надо так 👇

class Jedi {
  constructor() {}

  getName() {
    return this.name;
  }
}


class Rey extends Jedi {
  constructor(...args) {
    super(...args);
  }
}

 

✅ надо так 👇

class Rey extends Jedi {
  constructor(...args) {
    super(...args);
    this.name = 'Rey';
  }
}

 

3. Не дублируй методы в классах.

eslint: no-dupe-class-members

 

❌ не надо так 👇

class Foo {
  bar() { return 1; }
  bar() { return 2; }
}

 

✅ надо так 👇

class Foo {
  bar() { return 1; }
}

class Foo {
  bar() { return 2; }
}

⬆ Вернуться к содержанию

 

Модули.

 

1. Используйте один импорт на модуль, не дублируй импорты.

eslint: no-duplicate-imports

 

❌ не надо так 👇

import foo from 'foo';
// … другие import-ы … //
import { named1, named2 } from 'foo';

 

✅ надо так 👇

import foo, { named1, named2 } from 'foo';

// или так:
import foo, {
  named1,
  named2,
} from 'foo';

 

2. Не экспортируйте мутабельные переменные (которые могут измениться).

eslint: import/no-mutable-exports

 

❌ не надо так 👇

let foo = 3;
export { foo };

 

✅ надо так 👇

const foo = 3;
export { foo };

 

3. Все импорты должны объявляться в начале.

eslint: import/first

 

❌ не надо так 👇

import foo from 'foo';
foo.init();

import bar from 'bar';

 

✅ надо так 👇

import foo from 'foo';
import bar from 'bar';

foo.init();

 

4. Многострочные импорты пиши в столбик.

eslint: object-curly-newline

 

❌ не надо так 👇

import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';

 

✅ надо так 👇

import {
  longNameA,
  longNameB,
  longNameC,
  longNameD,
  longNameE,
} from 'path';

 

5. Не указывайте расширения файлов при импорте.

eslint import/extensions

 

❌ не надо так 👇

import foo from './foo.js';
import bar from './bar.jsx';
import baz from './baz/index.jsx';

 

✅ надо так 👇

import foo from './foo';
import bar from './bar';
import baz from './baz';

⬆ Вернуться к содержанию

 

Генераторы.

 

1. При использовании генераторов ставь один пробел перед * , но не ставь пробел после * .

eslint: generator-star-spacing

 

❌ не надо так 👇

function * generator() {}
let anonymous = function * () {};
let shorthand = {* generator() {} };

 

✅ надо так 👇

function *generator() {}
let anonymous = function *() {};
let shorthand = { *generator() {} };

⬆ Вернуться к содержанию

 

Операторы сравнения.

 

1. Используй === и !== (строгое сравнение ), вместо == и != (нестрогое сравнение).

eslint: eqeqeq

 

Это считается хорошей практикой, т.к. ты избегаешь неявного преобразования типов данных.

 

❌ не надо так 👇

a == b 
foo == true
bananas != 1
value == undefined

 

✅ надо так 👇

typeof foo === 'undefined'
'hello' !== 'world'
0 === 0
true === true
foo === null

Исключения:

  • сравнение двух литеральных значений:
  • вызов typeof;
  • сравнение с nullю

 

❌ не надо так 👇

a == b
foo == true
bananas != 1
value == undefined

 

✅ надо так 👇

typeof foo == 'undefined'
'hello' != 'world'
0 == 0
true == true
foo == null

 

2. Используйте фигурные скобки для создания блоков в case и default в конструкции switch...case , которые содержат лексические объявления (например, let, const, function и class).

eslint: no-case-declarations

 

Лексические объявления видны во всем блоке switch, но инициализируются только при срабатывании определенного case. Чтобы убедиться, что лексическое объявление применяется только к текущему case, необходимо использовать скобки.

 

❌ не надо так 👇

switch (foo) {
  case 1:
    let x = 1;
    break;
  case 2:
    const y = 2;
    break;
  case 3:
    function f() {
      // ...
    }
    break;
  default:
    class C {}
}

 

✅ надо так 👇

switch (foo) {
  case 1: {
    let x = 1;
    break;
  }
  case 2: {
    const y = 2;
    break;
  }
  case 3: {
    function f() {
      // ...
    }
    break;
  }
  case 4:
    bar();
    break;
  default: {
    class C {}
  }
}

 

3. Тернарные операторы не должны быть вложены.

eslint: no-nested-ternary

 

❌ не надо так 👇

const foo = maybe1 > maybe2
  ? "bar"
  : value1 > value2 ? "baz" : null;

const maybeNull = value1 > value2 ? 'baz' : null;

 

✅ надо так 👇

const foo = maybe1 > maybe2
  ? 'bar'
  : maybeNull;

//лучше так
const foo = maybe1 > maybe2 ? 'bar' : maybeNull;

 

4. Избегай ненужный тернарных операторов.

eslint: no-unneeded-ternary

 

❌ не надо так 👇

const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;

 

✅ надо так 👇

const foo = a || b;
const bar = !!c;
const baz = !c;

 

5. При смешивании операторов заключай их в скобки. Единственным исключением являются стандартные арифметические операторы: +, - и **, так как их приоритет широко понят. Рекомендуется заключать в скобки / и *, потому что их приоритет может быть неоднозначным, когда они смешаны.

eslint: no-mixed-operators

 

Это позволит избежать ошибок. Также код станет более читабельным

 

❌ не надо так 👇

const foo = a && b < 0 || c > 0 || d + 1 === 0;
const bar = a ** b - 5 % d;

if (a || b && c) {
  return d;
}

const bar = a + b / c * d;

 

✅ надо так 👇

const foo = (a && b < 0) || c > 0 || (d + 1 === 0);

const bar = a ** b - (5 % d);

if (a || (b && c)) {
  return d;
}

const bar = a + (b / c) * d;

 

6. Не повторяй условия в конструкции switch case.

eslint: no-duplicate-case

 

❌ не надо так 👇

let a = 1,
  one = 1;

switch (a) {
  case 1:
    break;
  case 2:
    break;
  case 1:         // дубликат
     break;
  default:
    break;
}

 

✅ надо так 👇

let a = 1,
  one = 1;
	
switch (a) {
  case 1:
    break;
  case 2:
    break;
  case 3:
    break;
  default:
    break;
}

 

7. Не используй в if, for, while, do...while или в тернарных выражениях в условиях постоянные выражения (литералы).

eslint: no-constant-condition

 

❌ не надо так 👇

if (false) {
  doSomethingUnfinished();
}

do {
  doSomethingForever();
} while (x = -1);

let result = 0 ? a : b;

 

✅ надо так 👇

if (x === 0) {
  doSomething();
}

while (typeof x === "undefined") {
  doSomething();
}

do {
  doSomething();
} while (x);
	
let result = x !== 0 ? a : b;

 

8. В условных выражениях не используй оператор присваивания = в условии.

eslint: no-cond-assign

 

Если тебе все-таки необходимо сделать присваивание в условии, то оберни это присваивание в круглые скобки

 

❌ не надо так 👇

let x;
if (x = 0) {
    var b = 1;
}

 

✅ надо так 👇

let x;
if (x === 0) {
 	   var b = 1;
}

 

9. В таких конструкция как if в условии, где результат выражения уже приведен к булевому типу (true/false) не приводи этот результат к булевому типу повторно с помощью двойного отрицания (!!) или Boolean().

eslint: no-extra-boolean-cast

 

❌ не надо так 👇

let foo = !!!bar;

let foo = !!bar ? baz : bat;

let foo = Boolean(!!bar);

let foo = new Boolean(!!bar);

if (!!foo) {
    // ...
}

if (Boolean(foo)) {
    // ...
}

while (!!foo) {
    // ...
}

do {
    // ...
} while (Boolean(foo));

for (; !!foo; ) {
    // ...
}

 

✅ надо так 👇

let foo = !!bar;
let foo = Boolean(bar);

function foo() {
    return !!bar;
}

let foo = bar ? !!baz : !!bat;

⬆ Вернуться к содержанию

 

Комментарии.

 

1. В комментариях после // или /* должен быть пробел.

eslint: spaced-comment

 

❌ не надо так 👇

//is current tab
const active = true;

/**
 *make() returns a new element
 *based on the passed-in tag name
 */
function make(tag) {

  // ...

  return element;
}

 

✅ надо так 👇

// is current tab
const active = true;


/**
 * make() returns a new element
 * based on the passed-in tag name
 */
function make(tag) {

  // ...

  return element;
}

⬆ Вернуться к содержанию

 

Пробелы.

 

1. Используйте отступ в 2 пробела. Таб можно настроить на 2 пробела.

eslint: indent

 

❌ не надо так 👇

function foo() {
∙∙∙∙let name;
}


function bar() {
∙let name;
}

 

✅ надо так 👇

function baz() {
∙∙let name;
}

 

2. Ставь пробел перед и после ключевого слова. Если ключевое слово начинается с начала строки, пробел не нужен. Пробел не нужен после имени функции перед списком аргументов.

eslint: keyword-spacing

 

❌ не надо так 👇

if(isJedi) {
  fight ();
}

function fight () {
  console.log ('Swooosh!');
}

 

✅ надо так 👇

if (isJedi) {
  fight();
}

function fight() {
  console.log('Swooosh!');
}

 

3. Ставь по одному пробелу вокруг операторов.

eslint: space-infix-ops

 

❌ не надо так 👇

const x=y+5;

 

✅ надо так 👇

const x = y + 5;

 

4. Не оставляйте в блоках пустые строки.

eslint: padded-blocks

 

❌ не надо так 👇

function bar() {

  console.log(foo);

}


if (baz) {

  console.log(qux);
} else {
  console.log(foo);

}


class Foo {

  constructor(bar) {
    this.bar = bar;
  }
}

 

✅ надо так 👇

function bar() {
  console.log(foo);
}


if (baz) {
  console.log(qux);
} else {
  console.log(foo);
}

 

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

eslint: no-multiple-empty-lines

 

❌ не надо так 👇

class Person {
  constructor(fullName, email, birthday) {
    this.fullName = fullName;


    this.email = email;


    this.setAge(birthday);
  }


  setAge(birthday) {
    const today = new Date();


    const age = this.getAge(today, birthday);


    this.age = age;
  }
}

 

✅ надо так 👇

class Person {
  constructor(fullName, email, birthday) {
    this.fullName = fullName;
    this.email = email;
    this.setAge(birthday);
  }

  setAge(birthday) {
    const today = new Date();
    const age = getAge(today, birthday);
    this.age = age;
  }
}

 

6. Не ставь пробел после открывающей круглой скобки и перед закрывающей круглой скобкой.

eslint: space-in-parens

 

❌ не надо так 👇

function bar( foo ) {
  return foo;
}

 

✅ надо так 👇

function bar(foo) {
  return foo;
}

 

7. Избегайте использования строк кода длинной более 100 символов (включая пробелы).

eslint: max-len

 

❌ не надо так 👇

const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;

$.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));

 

✅ надо так 👇

const foo = jsonData
  && jsonData.foo
  && jsonData.foo.bar
  && jsonData.foo.bar.baz
  && jsonData.foo.bar.baz.quux
  && jsonData.foo.bar.baz.quux.xyzzy;

$.ajax({
  method: 'POST',
  url: 'https://airbnb.com/',
  data: { name: 'John' },
})
  .done(() => console.log('Congratulations!'))
  .fail(() => console.log('You have failed this city.'));

 

8. Ставь один пробел после открывающей фигурной скобки и перед закрывающей в теле функций, условий если они написаны в строку.

eslint: block-spacing

 

❌ не надо так 👇

function foo() {return true;}
if (foo) { bar = 0;}

 

✅ надо так 👇

function foo() { return true; }
if (foo) { bar = 0; }

 

9. Не ставь пробел перед запятой, ставь пробел после запятой.

eslint: comma-spacing

 

❌ не надо так 👇

let foo = 1,bar = 2;
let arr = [1 , 2];

 

✅ надо так 👇

let foo = 1, bar = 2;
let arr = [1, 2];

 

10. При вызове функции не ставь пробел перед открывающей круглой скобкой.

eslint: func-call-spacing

 

❌ не надо так 👇

func ();

func
();

 

✅ надо так 👇

func();

 

11. Не ставь пробелы, табы в конце строк.

eslint: no-trailing-spaces

 

❌ не надо так 👇

let foo = 0;//•••••
let baz = 5;//••
//•••••

 

✅ надо так 👇

let foo = 0;
let baz = 5;

⬆ Вернуться к содержанию

 

Преобразование и приведение типов.

 

1. Не преобразовывай типы данных с помощью оператора new в String, Number и Boolean.

eslint: no-new-wrappers

 

❌ не надо так 👇

let stringObject = new String("Hello world");
let numberObject = new Number(33);
let booleanObject = new Boolean(false);

 

✅ надо так 👇

let text = String(someValue);
let num = Number(someValue);

⬆ Вернуться к содержанию

 

Методы отладки кода.

 

1. Не оставляй console.

eslint: no-console

 

Методы console хорошо подходят для отладки кода, однако их не должно быть в финальной версии кода.

 

❌ не надо так 👇

console.log("Log a debug level message.");
console.warn("Log a warn level message.");
console.error("Log an error level message.");

 

✅ надо так 👇

// Кастомный console
Console.log("Hello world!");

 

2. Рабочий код не должен содержать debugger.

eslint: no-debugger

❌ не надо так 👇

function isTruthy(x) {
    debugger;
    return Boolean(x);
}

 

✅ надо так 👇

function isTruthy(x) {
    return Boolean(x); // set a breakpoint at this line
}

⬆ Вернуться к содержанию

 

Регулярные выражения.

 

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

eslint: no-control-regex

 

❌ не надо так 👇

let pattern1 = /\x1f/;
let pattern2 = new RegExp("\x1f");

 

✅ надо так 👇

let pattern1 = /\x20/;
let pattern2 = new RegExp("\x20");

 

2. При использовании квадратных скобок [ ] в регулярных выражениях, они не должны быть пустыми.

eslint no-empty-character-class

 

❌ не надо так 👇

/^abc[]/.test("abcdefg"); // false
"abcdefg".match(/^abc[]/); // null

 

✅ надо так 👇

/^abc/.test("abcdefg"); // true
"abcdefg".match(/^abc/); // ["abc"]

/^abc[a-z]/.test("abcdefg"); // true
"abcdefg".match(/^abc[a-z]/); // ["abcd"]

⬆ Вернуться к содержанию

 

 

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors