# Руководство по написанию JavaScript-кода от [Airbnb](https://github.com/airbnb/javascript/)() {
*Наиболее разумный подход к написанию JavaScript-кода*
> **Замечание**: это руководство подразумевает использование [Babel](https://babeljs.io) вместе с [babel-preset-airbnb](https://npmjs.com/babel-preset-airbnb) или аналогом. Оно также предполагает установленный shims/polyfills в вашем приложении, такой как [airbnb-browser-shims](https://npmjs.com/airbnb-browser-shims) или аналог.
## Оглавление
1. [События](#events)
1. [jQuery](#jquery)
1. [Поддержка ECMAScript 5](#ecmascript-5-compatibility)
1. [Возможности ECMAScript 6+ (ES 2015+)](#ecmascript-6-es-2015-styles)
1. [Стандартная библиотека](#standard-library)
1. [Тестирование](#testing)
1. [Производительность](#performance)
1. [Ресурсы](#resources)
## <a name="events">События</a>
<a name="events--hash"></a><a name="24.1"></a>
- [25.1](#events--hash) Когда привязываете данные к событию (например, события `DOM` или какие-то собственные события, как `Backbone` события), передавайте литерал объекта (также известный как «хэш») вместо простого значения. Это позволяет другим разработчикам добавлять больше данных без поиска и изменения каждого обработчика события. К примеру, вместо:
```javascript
// плохо
$(this).trigger('listingUpdated', listing.id);
// ...
$(this).on('listingUpdated', (e, listingID) => {
// делает что-то с listingID
});
```
предпочитайте:
```javascript
// хорошо
$(this).trigger('listingUpdated', { listingID: listing.id });
// ...
$(this).on('listingUpdated', (e, data) => {
// делает что-то с data.listingID
});
```
**[⬆ к оглавлению](#Оглавление)**
## <a name="jquery">jQuery</a>
<a name="jquery--dollar-prefix"></a><a name="25.1"></a>
- [26.1](#jquery--dollar-prefix) Начинайте названия переменных, хранящих объект jQuery, со знака `$`.
```javascript
// плохо
const sidebar = $('.sidebar');
// хорошо
const $sidebar = $('.sidebar');
// хорошо
const $sidebarBtn = $('.sidebar-btn');
```
<a name="jquery--cache"></a><a name="25.2"></a>
- [26.2](#jquery--cache) Кэшируйте jQuery-поиски.
```javascript
// плохо
function setSidebar() {
$('.sidebar').hide();
// ...
$('.sidebar').css({
'background-color': 'pink',
});
}
// хорошо
function setSidebar() {
const $sidebar = $('.sidebar');
$sidebar.hide();
// ...
$sidebar.css({
'background-color': 'pink',
});
}
```
<a name="jquery--queries"></a><a name="25.3"></a>
- [26.3](#jquery--queries) Для поиска в DOM используйте каскады `$('.sidebar ul')` или селектор родитель > ребёнок `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
<a name="jquery--find"></a><a name="25.4"></a>
- [26.4](#jquery--find) Используйте функцию `find` для поиска в сохранённых jQuery-объектах.
```javascript
// плохо
$('ul', '.sidebar').hide();
// плохо
$('.sidebar').find('ul').hide();
// хорошо
$('.sidebar ul').hide();
// хорошо
$('.sidebar > ul').hide();
// хорошо
$sidebar.find('ul').hide();
```
**[⬆ к оглавлению](#Оглавление)**
## <a name="ecmascript-5-compatibility">Поддержка ECMAScript 5</a>
<a name="es5-compat--kangax"></a><a name="26.1"></a>
- [27.1](#es5-compat--kangax) Можно посмотреть в [таблице поддержки](https://kangax.github.io/es5-compat-table/) ES5 от пользователя [Kangax](https://twitter.com/kangax/) .
**[⬆ к оглавлению](#Оглавление)**
## <a name="ecmascript-6-es-2015-styles">Возможности ECMAScript 6+ (ES 2015+)</a>
<a name="es6-styles"></a><a name="27.1"></a>
- [28.1](#es6-styles) Здесь собраны ссылки на различные возможности ES6.
1. [Стрелочные функции](#arrow-functions)
1. [Классы и конструкторы](#classes--constructors)
1. [Сокращённая запись методов объекта](#es6-object-shorthand)
1. [Сокращённая запись свойств объекта](#es6-object-concise)
1. [Вычисляемые имена свойств объекта](#es6-computed-properties)
1. [Шаблонные строки](#es6-template-literals)
1. [Деструктуризация](#destructuring)
1. [Параметры по умолчанию](#es6-default-parameters)
1. [Оставшиеся параметры](#es6-rest)
1. [Оператор расширения](#es6-array-spreads)
1. [Let и Const](#references)
1. [Итераторы и генераторы](#iterators-and-generators)
1. [Модули](#modules)
<a name="tc39-proposals"></a>
- [28.2](#tc39-proposals) Не используйте [предложения TC39](https://github.com/tc39/proposals), которые не перешли на 3-ю стадию.
> Почему? [Они ещё не закончены](https://tc39.github.io/process-document/) и могут быть изменены или полностью изъяты. Мы хотим использовать JavaScript, а предложения ещё не стали частью JavaScript.
**[⬆ к оглавлению](#Оглавление)**
## <a name="standard-library">Стандартная библиотека</a>
[Стандартная библиотека](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects)
содержит утилиты, функциональность которых сломана, но они остались для поддержки старого кода.
<a name="standard-library--isnan"></a>
- [29.1](#standard-library--isnan) Используйте `Number.isNaN` вместо глобального `isNaN`.
eslint: [`no-restricted-globals`](https://eslint.org/docs/rules/no-restricted-globals)
> Почему? Глобальная функция `isNaN` приводит не-числа к числам, возвращая `true` для всего, что приводится к `NaN`.
> Если такое поведение необходимо, сделайте его явным.
```javascript
// плохо
isNaN('1.2'); // false
isNaN('1.2.3'); // true
// хорошо
Number.isNaN('1.2.3'); // false
Number.isNaN(Number('1.2.3')); // true
```
<a name="standard-library--isfinite"></a>
- [29.2](#standard-library--isfinite) Используйте `Number.isFinite` вместо глобального `isFinite`.
eslint: [`no-restricted-globals`](https://eslint.org/docs/rules/no-restricted-globals)
> Почему? Глобальная функция `isFinite` приводит не-числа к числам, возвращая `true` для всего, что приводится к конечному числу.
> Если такое поведение необходимо, сделайте его явным.
```javascript
// плохо
isFinite('2e3'); // true
// хорошо
Number.isFinite('2e3'); // false
Number.isFinite(parseInt('2e3', 10)); // true
```
**[⬆ к оглавлению](#Оглавление)**
## <a name="testing">Тестирование</a>
<a name="testing--yup"></a><a name="28.1"></a>
- [30.1](#testing--yup) **Ага.**
```javascript
function foo() {
return true;
}
```
<a name="testing--for-real"></a><a name="28.2"></a>
- [30.2](#testing--for-real) **Нет, но серьёзно**:
- Какой бы фреймворк вы не использовали, вы должны писать тесты!
- Стремитесь к тому, чтобы написать много маленьких чистых функций, и к тому, чтобы свести к минимуму места, где происходят мутации.
- Будьте осторожны со стабами (stubs) и моками (mocks) — они могут сделать ваше тестирование хрупким.
- Мы в первую очередь советуем вам использовать [`mocha`](https://www.npmjs.com/package/mocha) и [`jest`](https://www.npmjs.com/package/jest) от Airbnb. [`tape`](https://www.npmjs.com/package/tape) также иногда используется для небольших, отдельных модулей.
- 100% покрытие тестами — это хорошая цель, к которой надо стремиться, даже если это не всегда практично.
- Всякий раз, когда вы исправляете ошибку, _пишите регрессионный тест_. Исправленная ошибка без регрессионного тестирования почти наверняка всплывёт в будущем.
**[⬆ к оглавлению](#Оглавление)**
## <a name="performance">Производительность</a>
- [On Layout & Web Performance](https://www.kellegous.com/j/2013/01/26/layout-performance/)
- [String vs Array Concat](https://jsperf.com/string-vs-array-concat/2)
- [Try/Catch Cost In a Loop](https://jsperf.com/try-catch-in-loop-cost/12)
- [Bang Function](https://jsperf.com/bang-function)
- [jQuery Find vs Context, Selector](https://jsperf.com/jquery-find-vs-context-sel/164)
- [innerHTML vs textContent for script text](https://jsperf.com/innerhtml-vs-textcontent-for-script-text)
- [Long String Concatenation](https://jsperf.com/ya-string-concat/38)
- [Are JavaScript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta)
- Загрузка...
**[⬆ к оглавлению](#Оглавление)**
## <a name="resources">Ресурсы</a>
**Изучение ES6+**
- [Последняя спецификация ECMA](https://tc39.github.io/ecma262/)
- [ExploringJS](http://exploringjs.com/)
- [ES6 Compatibility Table](https://kangax.github.io/compat-table/es6/)
- [Comprehensive Overview of ES6 Features](http://es6-features.org/)
**Почитайте это**
- [Standard ECMA-262](http://www.ecma-international.org/ecma-262/6.0/index.html)
**Инструменты**
- Линтеры
- [ESlint](https://eslint.org/) - [Airbnb Style .eslintrc](https://github.com/airbnb/javascript/blob/master/linters/.eslintrc)
- [JSHint](http://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc)
- Neutrino Preset - [@neutrinojs/airbnb](https://neutrinojs.org/packages/airbnb/)
**Другие руководства**
- [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)
- [Google JavaScript Style Guide (Old)](https://google.github.io/styleguide/javascriptguide.xml)
- [jQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/js/)
- [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js)
- [StandardJS](https://standardjs.com)
**Другие стили**
- [Naming this in nested functions](https://gist.github.com/cjohansen/4135065) - Christian Johansen
- [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen
- [Popular JavaScript Coding Conventions on GitHub](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun
- [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman
**Дальнейшее чтение**
- [Understanding JavaScript Closures](https://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
- [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
- [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
- [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
- [Frontend Guidelines](https://github.com/bendc/frontend-guidelines) - Benjamin De Cock
**Книги**
- [JavaScript: The Good Parts](https://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
- [JavaScript Patterns](https://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
- [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
- [High Performance Web Sites: Essential Knowledge for Front-End Engineers](https://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
- [Maintainable JavaScript](https://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
- [JavaScript Web Applications](https://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
- [Pro JavaScript Techniques](https://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig
- [Smashing Node.js: JavaScript Everywhere](https://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch
- [Secrets of the JavaScript Ninja](https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
- [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg
- [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
- [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon
- [Third Party JavaScript](https://www.manning.com/books/third-party-javascript) - Ben Vinegar and Anton Kovalyov
- [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](http://amzn.com/0321812182) - David Herman
- [Eloquent JavaScript](http://eloquentjavascript.net/) - Marijn Haverbeke
- [You Don’t Know JS: ES6 & Beyond](http://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson
**Блоги**
- [JavaScript Weekly](http://javascriptweekly.com/)
- [JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/)
- [Bocoup Weblog](https://bocoup.com/weblog)
- [Adequately Good](http://www.adequatelygood.com/)
- [NCZOnline](https://www.nczonline.net/)
- [Perfection Kills](http://perfectionkills.com/)
- [Ben Alman](http://benalman.com/)
- [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/)
- [nettuts](http://code.tutsplus.com/?s=javascript)
**Подкасты**
- [JavaScript Air](https://javascriptair.com/)
- [JavaScript Jabber](https://devchat.tv/js-jabber/)
**[⬆ к оглавлению](#Оглавление)**