Руководство по написанию JavaScript-кода от Airbnb() {
Наиболее разумный подход к написанию JavaScript-кода
Замечание: это руководство подразумевает использование Babel вместе с babel-preset-airbnb или аналогом. Оно также предполагает установленный shims/polyfills в вашем приложении, такой как airbnb-browser-shims или аналог.
Это руководство также доступно на других языках. Смотрите Переводы.
Другие руководства
Оглавление
- Типы
- Объявление переменных
- Объекты
- Массивы
- Деструктуризация
- Строки
- Функции
- Стрелочные функции
- Классы и конструкторы
- Модули
- Итераторы и генераторы
- Свойства
- Переменные
- Подъём
- Операторы сравнения и равенства
- Блоки
- Управляющие операторы
- Комментарии
- Пробелы
- Запятые
- Точка с запятой
- Приведение типов
- Соглашение об именовании
- Аксессоры
- События
- jQuery
- Поддержка ECMAScript 5
- Возможности ECMAScript 6+ (ES 2015+)
- Стандартная библиотека
- Тестирование
- Производительность
- Ресурсы
- В реальной жизни
- Переводы
- Пообщаться с разработчиками Airbnb
- Участники перевода
- Лицензия
- Поправки
Типы
-
1.1 Простые типы: Когда вы взаимодействуете с простым типом, вы напрямую работаете с его значением.
stringnumberbooleannullundefinedsymbolbigint
const foo = 1; let bar = foo; bar = 9; console.log(foo, bar); // => 1, 9- Symbol и BigInt не могут быть полностью заполифиллены, поэтому они не должны использоваться, если разработка ведётся для браузеров или других сред, которые не поддерживают их нативно.
-
1.2 Сложные типы: Когда вы взаимодействуете со сложным типом, вы работаете со ссылкой на его значение.
objectarrayfunction
const foo = [1, 2]; const bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9
Объявление переменных
-
2.1 Используйте
constдля объявления переменных; избегайтеvar. eslint:prefer-const,no-const-assignПочему? Это гарантирует, что вы не сможете переопределять значения, т.к. это может привести к ошибкам и к усложнению понимания кода.
// плохо var a = 1; var b = 2; // хорошо const a = 1; const b = 2;
-
2.2 Если вам необходимо переопределять значения, то используйте
letвместоvar. eslint:no-varПочему? Область видимости
let— блок, уvar— функция.// плохо var count = 1; if (true) { count += 1; } // хорошо, используйте let. let count = 1; if (true) { count += 1; }
-
2.3 Помните, что у
letиconstблочная область видимости, в то время какvarимеет функциональную область видимости.// const и let существуют только в том блоке, в котором они определены. { let a = 1; const b = 1; var c = 1; } console.log(a); // ReferenceError console.log(b); // ReferenceError console.log(c); // 1В приведённом выше коде вы можете видеть, что ссылки на
aиbприведут к ошибкеReferenceError, в то время какcсодержит число. Это связано с тем, чтоaиbимеют блочную область видимости, в то время как уcфункциональная.
Объекты
-
3.1 Для создания объекта используйте литеральную нотацию. eslint:
no-new-object// плохо const item = new Object(); // хорошо const item = {};
-
3.2 Используйте вычисляемые имена свойств, когда создаёте объекты с динамическими именами свойств.
Почему? Они позволяют вам определить все свойства объекта в одном месте.
function getKey(k) { return `a key named ${k}`; } // плохо const obj = { id: 5, name: 'San Francisco', }; obj[getKey('enabled')] = true; // хорошо const obj = { id: 5, name: 'San Francisco', [getKey('enabled')]: true, };
-
3.3 Используйте сокращённую запись метода объекта. eslint:
object-shorthand// плохо const atom = { value: 1, addValue: function (value) { return atom.value + value; }, }; // хорошо const atom = { value: 1, addValue(value) { return atom.value + value; }, };
-
3.4 Используйте сокращённую запись свойств объекта. eslint:
object-shorthandПочему? Это короче и понятнее.
const lukeSkywalker = 'Luke Skywalker'; // плохо const obj = { lukeSkywalker: lukeSkywalker, }; // хорошо const obj = { lukeSkywalker, };
-
3.5 Группируйте ваши сокращённые записи свойств в начале объявления объекта.
Почему? Так легче сказать, какие свойства используют сокращённую запись.
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, };
-
3.6 Только недопустимые идентификаторы помещаются в кавычки. eslint:
quote-propsПочему? На наш взгляд, такой код легче читать. Это улучшает подсветку синтаксиса, а также облегчает оптимизацию для многих JS-движков.
// плохо const bad = { 'foo': 3, 'bar': 4, 'data-blah': 5, }; // хорошо const good = { foo: 3, bar: 4, 'data-blah': 5, };
-
3.7 Не вызывайте напрямую методы
Object.prototype, такие какhasOwnProperty,propertyIsEnumerable, иisPrototypeOf. eslint:no-prototype-builtinsПочему? Эти методы могут быть переопределены в свойствах объекта, который мы проверяем
{ hasOwnProperty: false }, или этот объект может бытьnull(Object.create(null)).// плохо console.log(object.hasOwnProperty(key)); // хорошо console.log(Object.prototype.hasOwnProperty.call(object, key)); // отлично const has = Object.prototype.hasOwnProperty; // Кэшируем запрос в рамках модуля. console.log(has.call(object, key)); /* или */ import has from 'has'; // https://www.npmjs.com/package/has console.log(has(object, key));
-
3.8 Используйте синтаксис расширения вместо
Object.assignдля поверхностного копирования объектов. Используйте параметр оставшихся свойств, чтобы получить новый объект с некоторыми опущенными свойствами. eslint:prefer-object-spread// очень плохо 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 }