-
Используйте
const
для объявления переменных; избегайтеvar
. eslint:prefer-const
,no-const-assign
Почему? Это гарантирует, что вы не сможете переопределять значения, т.к. это может привести к ошибкам и к усложнению понимания кода.
// плохо var a = 1; var b = 2; // хорошо const a = 1; const b = 2;
-
Если вам необходимо переопределять значения, то используйте
let
вместоvar
. eslint:no-var
Почему? Область видимости
let
— блок, уvar
— функция.// плохо var count = 1; if (true) { count += 1; } // хорошо, используйте let. let count = 1; if (true) { count += 1; }
-
Используйте сокращённую запись метода объекта. eslint:
object-shorthand
// плохо const atom = { value: 1, addValue: function (value) { return atom.value + value; }, }; // хорошо const atom = { value: 1, addValue(value) { return atom.value + value; }, };
-
Используйте сокращённую запись свойств объекта. eslint:
object-shorthand
Почему? Это короче и понятнее.
const lukeSkywalker = 'Luke Skywalker'; // плохо const obj = { lukeSkywalker: lukeSkywalker, }; // хорошо const obj = { lukeSkywalker, };
-
Группируйте ваши сокращённые записи свойств в начале объявления объекта.
Почему? Так легче сказать, какие свойства используют сокращённую запись.
const anakinSkywalker = 'Anakin Skywalker'; const lukeSkywalker = 'Luke Skywalker'; // плохо const obj = { episodeOne: 1, twoJediWalkIntoACantina: 2, lukeSkywalker, episodeThree: 3, mayTheFourth: 4, anakinSkywalker, }; // хорошо const obj = { lukeSkywalker, anakinSkywalker, episodeOne: 1, twoJediWalkIntoACantina: 2, episodeThree: 3, mayTheFourth: 4, };
-
Используйте оператор расширения вместо
Object.assign
для поверхностного копирования объектов. Используйте синтаксис оставшихся свойств, чтобы получить новый объект с некоторыми опущенными свойствами.// очень плохо const original = { a: 1, b: 2 }; const copy = Object.assign(original, { c: 3 }); // эта переменная изменяет `original` ಠ_ಠ delete copy.a; // если сделать так // плохо const original = { a: 1, b: 2 }; const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 } // хорошо const original = { a: 1, b: 2 }; const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 } const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
-
Для создания массива используйте литеральную нотацию. eslint:
no-array-constructor
// плохо const items = new Array(); // хорошо const items = [];
-
Для добавления элемента в массив используйте Array#push вместо прямого присваивания.
const someStack = []; // плохо someStack[someStack.length] = 'abracadabra'; // хорошо someStack.push('abracadabra');
-
Для копирования массивов используйте оператор расширения
...
.// плохо const len = items.length; const itemsCopy = []; let i; for (i = 0; i < len; i += 1) { itemsCopy[i] = items[i]; } // хорошо const itemsCopy = [...items];
-
Если массив располагается на нескольких строках, то используйте разрывы строк после открытия и перед закрытием скобок.
// плохо const arr = [ [0, 1], [2, 3], [4, 5], ]; const objectInArray = [{ id: 1, }, { id: 2, }]; const numberInArray = [ 1, 2, ]; // хорошо const arr = [[0, 1], [2, 3], [4, 5]]; const objectInArray = [ { id: 1, }, { id: 2, }, ]; const numberInArray = [ 1, 2, ];
-
При обращении к нескольким свойствам объекта используйте деструктуризацию объекта. eslint:
prefer-destructuring
Почему? Деструктуризация избавляет вас от создания временных переменных для этих свойств.
// плохо function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `${firstName} ${lastName}`; } // хорошо function getFullName(user) { const { firstName, lastName } = user; return `${firstName} ${lastName}`; } // отлично function getFullName({ firstName, lastName }) { return `${firstName} ${lastName}`; }
-
Используйте деструктуризацию массивов. eslint:
prefer-destructuring
const arr = [1, 2, 3, 4]; // плохо const first = arr[0]; const second = arr[1]; // хорошо const [first, second] = arr;
-
Используйте одинарные кавычки
''
для строк. eslint:quotes
// плохо const name = "Capt. Janeway"; // плохо - литерал шаблонной строки должен содержать интерполяцию или переводы строк const name = `Capt. Janeway`; // хорошо const name = 'Capt. Janeway';
-
Строки, у которых в строчке содержится более 100 символов, не пишутся на нескольких строчках с использованием конкатенации.
Почему? Работать с разбитыми строками неудобно и это затрудняет поиск по коду.
// плохо const errorMessage = 'This is a super long error that was thrown because \ of Batman. When you stop to think about how Batman had anything to do \ with this, you would get nowhere \ fast.'; // плохо const errorMessage = 'This is a super long error that was thrown because ' + 'of Batman. When you stop to think about how Batman had anything to do ' + 'with this, you would get nowhere fast.'; // хорошо const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
-
При создании строки программным путём используйте шаблонные строки вместо конкатенации. 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}?`; }
-
Никогда не используйте
eval()
, т.к. это открывает множество уязвимостей. eslint:no-eval
-
Используйте синтаксис записи аргументов по умолчанию, а не изменяйте аргументы функции.
// очень плохо function handleThings(opts) { // Нет! Мы не должны изменять аргументы функции. // Плохо вдвойне: если переменная opts будет ложной, // то ей присвоится пустой объект, а не то что вы хотели. // Это приведёт к коварным ошибкам. opts = opts || {}; // ... } // всё ещё плохо function handleThings(opts) { if (opts === void 0) { opts = {}; } // ... } // хорошо function handleThings(opts = {}) { // ... }
-
Отступы при определении функции. eslint:
space-before-function-paren
space-before-blocks
Почему? Однородность кода — это хорошо. Вам не надо будет добавлять или удалять пробел при манипуляции с именем.
// плохо const f = function(){}; const g = function (){}; const h = function() {}; // хорошо const x = function () {}; const y = function a() {};
-
Никогда не изменяйте параметры. eslint:
no-param-reassign
Почему? Манипуляция объектами, приходящими в качестве параметров, может вызывать нежелательные побочные эффекты в вызывающей функции.
// плохо function f1(obj) { obj.key = 1; } // хорошо function f2(obj) { const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1; }
-
Никогда не переназначайте параметры. eslint:
no-param-reassign
Почему? Переназначенные параметры могут привести к неожиданному поведению, особенно при обращении к
arguments
. Это также может вызывать проблемы оптимизации, особенно в V8.// плохо function f1(a) { a = 1; // ... } function f2(a) { if (!a) { a = 1; } // ... } // хорошо function f3(a) { const b = a || 1; // ... } function f4(a = 1) { // ... }
-
Функции с многострочным определением или запуском должны содержать такие же отступы, как и другие многострочные списки в этом списке: с каждым элементом на отдельной строке, с запятой в конце элемента. eslint:
function-paren-newline
// плохо function foo(bar, baz, quux) { // ... } // хорошо function foo( bar, baz, quux, ) { // ... } // плохо console.log(foo, bar, baz); // хорошо console.log( foo, bar, baz, );
-
Когда вам необходимо использовать анонимную функцию (например, при передаче встроенной функции обратного вызова), используйте стрелочную функцию. eslint:
prefer-arrow-callback
,arrow-spacing
Почему? Таким образом создаётся функция, которая выполняется в контексте
this
, который мы обычно хотим, а также это более короткий синтаксис.Почему бы и нет? Если у вас есть довольно сложная функция, вы можете переместить эту логику внутрь её собственного именованного функционального выражения.
// плохо [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; });
-
Если тело функции состоит из одного оператора, возвращающего выражение без побочных эффектов, то опустите фигурные скобки и используйте неявное возвращение. В противном случае, сохраните фигурные скобки и используйте оператор
return
. eslint:arrow-parens
,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}.`); // хорошо [1, 2, 3].map((number) => { const nextNumber = number + 1; return `A string containing the ${nextNumber}.`; }); // хорошо [1, 2, 3].map((number, index) => ({ [index]: number, })); // Неявный возврат с побочными эффектами function foo(callback) { const val = callback(); if (val === true) { // Сделать что-то, если функция обратного вызова вернёт true } } let bool = false; // плохо foo(() => bool = true); // хорошо foo(() => { bool = true; });
-
Избегайте схожести стрелочной функции (
=>
) с операторами сравнения (<=
,>=
). eslint:no-confusing-arrow
```javascript
// плохо
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
```javascript
// плохо
(foo) =>
bar;
(foo) =>
(bar);
// хорошо
(foo) => bar;
(foo) => (bar);
(foo) => (
bar
)
```
-
Избегайте дублирующих членов класса. eslint:
no-dupe-class-members
Почему? Если объявление члена класса повторяется, без предупреждения будет использовано последнее. Наличие дубликатов скорее всего приведёт к ошибке.
// плохо class Foo { bar() { return 1; } bar() { return 2; } } // хорошо class Foo { bar() { return 1; } } // хорошо class Foo { bar() { return 2; } }
-
В модулях с единственным экспортом предпочтительнее использовать экспорт по умолчанию, а не экспорт по имени. eslint:
import/prefer-default-export
Почему? Для того чтобы поощрять создание множества файлов, которые бы экспортировали одну сущность, т.к. это лучше для читабельности и поддержки кода.
// плохо export function foo() {} // хорошо export default function foo() {}
-
Не используйте итераторы. Применяйте функции высшего порядка вместо таких циклов как
for-in
илиfor-of
. eslint:no-iterator
no-restricted-syntax
Почему? Это обеспечивает соблюдение нашего правила о неизменности переменных. Работать с чистыми функциями, которые возвращают значение, проще, чем с функциями с побочными эффектами.
Используйте
map()
/every()
/filter()
/find()
/findIndex()
/reduce()
/some()
/ ... для итерации по массивам, аObject.keys()
/Object.values()
/Object.entries()
для создания массивов, с помощью которых можно итерироваться по объектам.const numbers = [1, 2, 3, 4, 5]; // плохо let sum = 0; for (let num of numbers) { sum += num; } sum === 15; // хорошо let sum = 0; numbers.forEach((num) => { sum += num; }); sum === 15; // отлично (используйте силу функций) const sum = numbers.reduce((total, num) => total + num, 0); sum === 15; // плохо const increasedByOne = []; for (let i = 0; i < numbers.length; i++) { increasedByOne.push(numbers[i] + 1); } // хорошо const increasedByOne = []; numbers.forEach((num) => { increasedByOne.push(num + 1); }); // отлично (продолжайте в том же духе) const increasedByOne = numbers.map((num) => num + 1);
-
В первую очередь группируйте
const
, а затемlet
.Почему? Это полезно, когда в будущем вам понадобится создать переменную, зависимую от предыдущих.
// плохо let i, len, dragonball, items = getItems(), goSportsTeam = true; // плохо let i; const items = getItems(); let dragonball; const goSportsTeam = true; let len; // хорошо const goSportsTeam = true; const items = getItems(); let dragonball; let i; let length;
-
Создавайте переменные там, где они вам необходимы, но помещайте их в подходящее место.
Почему?
let
иconst
имеют блочную область видимости, а не функциональную.// плохо - вызов ненужной функции function checkName(hasName) { const name = getName(); if (hasName === 'test') { return false; } if (name === 'test') { this.setName(''); return false; } return name; } // хорошо function checkName(hasName) { if (hasName === 'test') { return false; } const name = getName(); if (name === 'test') { this.setName(''); return false; } return name; }
-
Избегайте использования унарных инкрементов и декрементов (
++
,--
). eslintno-plusplus
Почему? Согласно документации eslint, унарные инкремент и декремент автоматически вставляют точку с запятой, что может стать причиной трудноуловимых ошибок при инкрементировании и декрементировании значений. Также нагляднее изменять ваши значения таким образом
num += 1
вместоnum++
илиnum ++
. Запрет на унарные инкремент и декремент ограждает вас от непреднамеренных преждевременных инкрементаций/декрементаций значений, которые могут привести к непредсказуемому поведению вашей программы.// плохо const array = [1, 2, 3]; let num = 1; num++; --num; let sum = 0; let truthyCount = 0; for (let i = 0; i < array.length; i++) { let value = array[i]; sum += value; if (value) { truthyCount++; } } // хорошо const array = [1, 2, 3]; let num = 1; num += 1; num -= 1; const sum = array.reduce((a, b) => a + b, 0); const truthyCount = array.filter(Boolean).length;
-
Используйте
===
и!==
вместо==
и!=
. eslint:eqeqeq
-
Используйте сокращения для булевских типов, а для строк и чисел применяйте явное сравнение.
// плохо if (isValid === true) { // ... } // хорошо if (isValid) { // ... } // плохо if (name) { // ... } // хорошо if (name !== '') { // ... } // плохо if (collection.length) { // ... } // хорошо if (collection.length > 0) { // ... }
-
При смешивании операторов, помещайте их в круглые скобки. Единственным исключением являются стандартные арифметические операторы:
+
,-
и**
, так как их приоритет широко известен. Мы рекомендуем заключить/
и*
в круглые скобки, поскольку их приоритет может быть неоднозначным, когда они смешиваются. eslint:no-mixed-operators
Почему? Это улучшает читаемость и уточняет намерения разработчика.
// плохо const foo = a && b < 0 || c > 0 || d + 1 === 0; // плохо const bar = a ** b - 5 % d; // плохо // можно ошибиться, думая что это (a || b) && c 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;
-
Если блоки кода в условии
if
иelse
занимают несколько строк, расположите операторelse
на той же строчке, где находится закрывающая фигурная скобка блокаif
. eslint:brace-style
// плохо if (test) { thing1(); thing2(); } else { thing3(); } // хорошо if (test) { thing1(); thing2(); } else { thing3(); }
-
Если в блоке
if
всегда выполняется операторreturn
, последующий блокelse
не нужен.return
внутри блокаelse if
, следующем за блокомif
, который содержитreturn
, может быть разделён на несколько блоков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; } }
-
Если ваш управляющий оператор (
if
,while
и т.д.) слишком длинный или превышает максимальную длину строки, то каждое (сгруппированное) условие можно поместить на новую строку. Логический оператор должен располагаться в начале строки. Громоздкие и сложные для понимания условные конструкции рекомендуется дополнительно разбивать и выносить в отдельные переменные.Почему? Наличие операторов в начале строки приводит к выравниванию операторов и напоминает цепочку методов. Это также улучшает читаемость, упрощая визуальное отслеживание сложной логики.
// плохо if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) { thing1(); } // плохо if (foo === 123 && bar === 'abc') { thing1(); } // плохо if (foo === 123 && bar === 'abc') { thing1(); } // плохо if ( foo === 123 && bar === 'abc' ) { thing1(); } // хорошо if ( foo === 123 && bar === 'abc' ) { thing1(); } // хорошо if ( (foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening() ) { thing1(); } // хорошо if (foo === 123 && bar === 'abc') { thing1(); }
-
Ставьте 1 пробел перед открывающей фигурной скобкой у блока. eslint:
space-before-blocks
// плохо function test(){ console.log('test'); } // хорошо function test() { console.log('test'); } // плохо dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog', }); // хорошо dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog', });
-
Ставьте 1 пробел перед открывающей круглой скобкой в операторах управления (
if
,while
и т.п.). Не оставляйте пробелов между списком аргументов и названием в объявлениях и вызовах функций. eslint:keyword-spacing
// плохо if(isJedi) { fight (); } // хорошо if (isJedi) { fight(); } // плохо function fight () { console.log ('Swooosh!'); } // хорошо function fight() { console.log('Swooosh!'); }
-
Разделяйте операторы пробелами. eslint:
space-infix-ops
// плохо const x=y+5; // хорошо const x = y + 5;
-
Используйте переносы строк и отступы, когда делаете длинные цепочки методов (больше 2 методов). Ставьте точку в начале строки, чтобы дать понять, что это не новая инструкция, а продолжение цепочки. eslint:
newline-per-chained-call
no-whitespace-before-property
// плохо $('#items').find('.selected').highlight().end().find('.open').updateCount(); // плохо $('#items'). find('.selected'). highlight(). end(). find('.open'). updateCount(); // хорошо $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount(); // плохо const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', `translate(${radius + margin},${radius + margin})`) .call(tron.led); // хорошо const leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .classed('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', `translate(${radius + margin},${radius + margin})`) .call(tron.led); // хорошо const leds = stage.selectAll('.led').data(data);
-
Оставляйте пустую строку между блоком кода и следующей инструкцией.
// плохо if (foo) { return bar; } return baz; // хорошо if (foo) { return bar; } return baz; // плохо const obj = { foo() { }, bar() { }, }; return obj; // хорошо const obj = { foo() { }, bar() { }, }; return obj; // плохо const arr = [ function foo() { }, function bar() { }, ]; return arr; // хорошо const arr = [ function foo() { }, function bar() { }, ]; return arr;
-
Не добавляйте пробелы между квадратными скобками и их содержимым. eslint:
array-bracket-spacing
// плохо const foo = [ 1, 2, 3 ]; console.log(foo[ 0 ]); // хорошо const foo = [1, 2, 3]; console.log(foo[0]);
-
Добавляйте пробелы между фигурными скобками и их содержимым. eslint:
object-curly-spacing
// плохо const foo = {clark: 'kent'}; // хорошо const foo = { clark: 'kent' };
-
Старайтесь не допускать, чтобы строки были длиннее 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.'));
-
Избегайте пробелов между функциями и их вызовами. eslint:
func-call-spacing
// плохо func (); func (); // хорошо func();
-
Обеспечьте согласованное расстояние между ключами и значениями в свойствах литералов объекта. eslint:
key-spacing
// плохо var obj = { "foo" : 42 }; var obj2 = { "foo":42 }; // хорошо var obj = { "foo": 42 };
-
Избегайте пробелов в конце строки. eslint:
no-trailing-spaces
-
Добавляйте точку с запятой в конце инструкций. eslint:
semi
Почему? Когда JavaScript встречает перенос строки без точки с запятой, он использует правило под названием Автоматическая Вставка Точки с запятой (Automatic Semicolon Insertion), чтобы определить, стоит ли считать этот перенос строки как конец выражения и (как следует из названия) поместить точку с запятой в вашем коде до переноса строки. Однако, ASI содержит несколько странных форм поведения, и ваш код может быть сломан, если JavaScript неверно истолкует ваш перенос строки. Эти правила станут сложнее, когда новые возможности станут частью JavaScript. Явное завершение ваших выражений и настройка вашего линтера для улавливания пропущенных точек с запятыми помогут вам предотвратить возникновение проблем.
// плохо - выбрасывает исключение const luke = {} const leia = {} [luke, leia].forEach((jedi) => jedi.father = 'vader') // плохо - выбрасывает исключение const reaction = "No! That’s impossible!" (async function meanwhileOnTheFalcon() { // переносимся к `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() { // переносимся к `leia`, `lando`, `chewie`, `r2`, `c3p0` // ... }()); // хорошо function foo() { return 'search your feelings, you know it to be foo'; }
-
Избегайте названий из одной буквы. Имя должно быть наглядным. eslint:
id-length
// плохо function q() { // ... } // хорошо function query() { // ... }
-
Используйте
camelCase
для именования объектов, функций и экземпляров. eslint:camelcase
// плохо const OBJEcttsssss = {}; const this_is_my_object = {}; function c() {} // хорошо const thisIsMyObject = {}; function thisIsMyFunction() {}
-
Используйте
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', });
-
Не используйте
_
в начале или в конце названий. eslint:no-underscore-dangle
Почему? JavaScript не имеет концепции приватности свойств или методов. Хотя подчёркивание в начале имени является распространённым соглашением, которое показывает «приватность», фактически эти свойства являются такими же доступными, как и часть вашего публичного API. Это соглашение может привести к тому, что разработчики будут ошибочно думать, что изменения не приведут к поломке или что тесты не нужны. Итог: если вы хотите, чтобы что-то было «приватным», то оно не должно быть доступно извне.
Добавлю так же что у Vue могут быть проблемы со свойствами начинающимися с $ и _
// плохо this.__firstName__ = 'Panda'; this.firstName_ = 'Panda'; this._firstName = 'Panda'; // хорошо this.firstName = 'Panda'; // хорошо, в средах, где поддерживается WeakMaps // смотрите https://kangax.github.io/compat-table/es6/#test-WeakMap const firstNames = new WeakMap(); firstNames.set(this, 'Panda');
-
Не сохраняйте ссылку на
this
. Используйте стрелочные функции или метод bind().// плохо function foo() { const self = this; return function () { console.log(self); }; } // плохо function foo() { const that = this; return function () { console.log(that); }; } // хорошо function foo() { return () => { console.log(this); }; }
-
Сокращения или буквенные аббревиатуры всегда должны быть в верхнем или нижнем регистре.
Почему? Имена предназначены для удобства чтения.
// плохо import SmsContainer from './containers/SmsContainer'; // плохо const HttpRequests = [ // ... ]; // хорошо import SMSContainer from './containers/SMSContainer'; // хорошо const HTTPRequests = [ // ... ]; // также хорошо const httpRequests = [ // ... ]; // отлично import TextMessageContainer from './containers/TextMessageContainer'; // отлично const requests = [ // ... ];
-
Если свойство/метод возвращает логический тип, то используйте названия
isVal()
илиhasVal()
.// плохо if (!dragon.age()) { return false; } // хорошо if (!dragon.hasAge()) { return false; }
-
Используйте
Number.isNaN
вместо глобальногоisNaN
. eslint:no-restricted-globals
Почему? Глобальная функция
isNaN
приводит не-числа к числам, возвращаяtrue
для всего, что приводится кNaN
. Если такое поведение необходимо, сделайте его явным.// плохо isNaN('1.2'); // false isNaN('1.2.3'); // true // хорошо Number.isNaN('1.2.3'); // false Number.isNaN(Number('1.2.3')); // true
-
Используйте
Number.isFinite
вместо глобальногоisFinite
. eslint:no-restricted-globals
Почему? Глобальная функция
isFinite
приводит не-числа к числам, возвращаяtrue
для всего, что приводится к конечному числу. Если такое поведение необходимо, сделайте его явным.// плохо isFinite('2e3'); // true // хорошо Number.isFinite('2e3'); // false Number.isFinite(parseInt('2e3', 10)); // true
-
Не используйте в строках необязательные экранирующие символы. eslint:
no-useless-escape
Почему? Обратные слеши ухудшают читабельность, поэтому они должны быть только при необходимости.
// плохо const foo = '\'this\' \i\s \"quoted\"'; // хорошо const foo = '\'this\' is "quoted"'; const foo = `my name is '${name}'`;