# Руководство по написанию 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/) **[⬆ к оглавлению](#Оглавление)**