В данном руководстве описаны подходы по оформлению Java Script. Данное руководство не является железным правилом для всех проектов во frontend, а только рекомендации для разработки проектов в нашей школе 🙂 На вашей работе могут быть другие правила. Все правила обсуждаются и согласовываются участниками команды и придерживаются их на протяжении разработки всего проекта.
- Соглашение об именовании
- Переменные
- Объявление переменных
- Запятые
- Точка с запятой
- Блоки
- Объекты
- Массивы
- Деструктуризация
- Строки
- Функции
- Стрелочные функции
- Классы и конструкторы
- Модули
- Генераторы
- Операторы сравнения
- Комментарии
- Пробелы
- Преобразование и приведение типов
- Регулярные выражения
eslint:
id-length
❌ не надо так 👇
function q() {
// ...
}
✅ надо так 👇
function query() {
// ...
}
eslint:
camelcase
❌ не надо так 👇
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}
✅ надо так 👇
const thisIsMyObject = {};
function thisIsMyFunction() {}
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',
});
eslint:
no-underscore-dangle
❌ не надо так 👇
let name_ = 'Max';
foo._bar();
✅ надо так 👇
let name = 'Max';
foo.bar();
Исключения:
- разрешено использовать нижнее подчеркивание после this.
Так принято помечать псевдоприватные поля.
✅ надо так 👇
this._bar();
let a = this.foo_;
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;
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
eslint :
operator-linebreak
При нарушении правила max-len оборачивай присваивание в скобки.
❌ не надо так 👇
const foo =
superLongLongLongLongLongLongLongLongFunctionName();
const foo
= 'superLongLongLongLongLongLongLongLongString';
✅ надо так 👇
const foo = (
superLongLongLongLongLongLongLongLongFunctionName()
);
const foo = 'superLongLongLongLongLongLongLongLongString';
eslint:
no-unused-vars
❌ не надо так 👇
let x = 0;
let y = 1; // Переменная не используется
function getX() {
return x + 1;
}
✅ надо так 👇
let x = 0;
function getX() {
return x + 1;
}
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;
}
eslint:
no-var
❌ не надо так 👇
var x = "y";
var CONFIG = {};
✅ надо так 👇
let x = "y";
const CONFIG = {};
eslint:
comma-style
❌ не надо так 👇
const story = [
once
, upon
, aTime
];
✅ надо так 👇
const story = [
once,
upon,
aTime,
];
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
}
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';
}
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;
}
}
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 */
}
eslint:
no-new-object
❌ не надо так 👇
const item = new Object();
✅ надо так 👇
const item = {};
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));
eslint:
key-spacing
❌ не надо так 👇
let obj = { "foo" : 42 };
✅ надо так 👇
let obj = { "foo": 42 };
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';
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
]
};
eslint:
dot-notation
❌ не надо так 👇
const luke = {
jedi: true,
age: 28,
};
const isJedi = luke['jedi'];
✅ надо так 👇
const isJedi = luke.jedi;
eslint:
no-array-constructor
❌ не надо так 👇
const items = new Array();
✅ надо так 👇
const items = [];
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;
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;
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}`;
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}?`;
}
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 = () => {};
eslint:
wrap-iife
❌ не надо так 👇
const x = function () { return { y: 1 };}();
const x = (function () { return { y: 1 };})();
✅ надо так 👇
const x = (function () { return { y: 1 };}())
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();
}
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);
}
eslint:
no-new-func
❌ не надо так 👇
const add = new Function('a', 'b', 'return a + b');
✅ надо так 👇
const subtract = Function('a', 'b', 'return a - b');
❌ не надо так 👇
const f = function(){};
const g = function (){};
const h = function() {};
✅ надо так 👇
const x = function () {};
const y = function a() {};
eslint:
no-param-reassign
❌ не надо так 👇
function foo(bar) {
bar = 13;
}
function foo(bar) {
bar++;
}
✅ надо так 👇
function foo(bar) {
let baz = bar;
}
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);
};
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}.`);
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;
};
eslint:
implicit-arrow-linebreak
❌ не надо так 👇
foo =>
bar;
foo =>
(bar);
✅ надо так 👇
foo => bar;
foo => (bar);
foo => (
bar
)
eslint:
new-cap
❌ не надо так 👇
const colleague = new person();
const friend = new person.acquaintance();
✅ надо так 👇
const colleague = new Person();
const friend = new person.Acquaintance();
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';
}
}
eslint:
no-dupe-class-members
❌ не надо так 👇
class Foo {
bar() { return 1; }
bar() { return 2; }
}
✅ надо так 👇
class Foo {
bar() { return 1; }
}
class Foo {
bar() { return 2; }
}
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';
eslint:
import/no-mutable-exports
❌ не надо так 👇
let foo = 3;
export { foo };
✅ надо так 👇
const foo = 3;
export { foo };
eslint:
import/first
❌ не надо так 👇
import foo from 'foo';
foo.init();
import bar from 'bar';
✅ надо так 👇
import foo from 'foo';
import bar from 'bar';
foo.init();
eslint:
object-curly-newline
❌ не надо так 👇
import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
✅ надо так 👇
import {
longNameA,
longNameB,
longNameC,
longNameD,
longNameE,
} from 'path';
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';
eslint:
generator-star-spacing
❌ не надо так 👇
function * generator() {}
let anonymous = function * () {};
let shorthand = {* generator() {} };
✅ надо так 👇
function *generator() {}
let anonymous = function *() {};
let shorthand = { *generator() {} };
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 {}
}
}
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;
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;
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;
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;
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;
}
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!');
}
eslint:
space-infix-ops
❌ не надо так 👇
const x=y+5;
✅ надо так 👇
const x = y + 5;
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);
}
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;
}
}
eslint:
space-in-parens
❌ не надо так 👇
function bar( foo ) {
return foo;
}
✅ надо так 👇
function bar(foo) {
return foo;
}
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; }
eslint:
comma-spacing
❌ не надо так 👇
let foo = 1,bar = 2;
let arr = [1 , 2];
✅ надо так 👇
let foo = 1, bar = 2;
let arr = [1, 2];
eslint:
func-call-spacing
❌ не надо так 👇
func ();
func
();
✅ надо так 👇
func();
eslint:
no-trailing-spaces
❌ не надо так 👇
let foo = 0;//•••••
let baz = 5;//••
//•••••
✅ надо так 👇
let foo = 0;
let baz = 5;
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);
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!");
eslint:
no-debugger
❌ не надо так 👇
function isTruthy(x) {
debugger;
return Boolean(x);
}
✅ надо так 👇
function isTruthy(x) {
return Boolean(x); // set a breakpoint at this line
}
eslint:
no-control-regex
❌ не надо так 👇
let pattern1 = /\x1f/;
let pattern2 = new RegExp("\x1f");
✅ надо так 👇
let pattern1 = /\x20/;
let pattern2 = new RegExp("\x20");
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"]
