Skip to content

RslnMtvv/javascript

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Стиль написания кода на JavaScript для Uprock: Перевод и расширение Airbnb JavaScript Style Guide

Наиболее разумный подход к JavaScript

  1. Типы
  2. Объекты
  3. Массивы
  4. Строки
  5. Функции
  6. Свойства
  7. Переменные
  8. Области видимости
  9. Условные выражения и равенства
  10. Блоки кода
  11. Комментарии
  12. Пробелы
  13. Запятые
  14. Точки с запятой
  15. Приведение типов
  16. Соглашение об именовании
  17. Геттеры и сеттеры
  18. Конструкторы
  19. События
  20. Модули
  21. jQuery
  22. Совместимость с ES5
  23. Тестирование
  24. Быстродействие
  25. Ресурсы
  26. В реальном мире
  27. Переводы
  28. Лицензия
  • Простые типы: Когда вы взаимодействуете с простым типом, вы взаимодействуете непосредственно с его значением в памяти.

    • string
    • number
    • boolean
    • null
    • undefined
    var foo = 1,
        bar = foo;
    
    bar = 9;
    
    console.log(foo, bar); // => 1, 9. foo не изменился
  • Сложные типы: Когда вы взаимодействуете со сложным типом, вы взаимодействуете с ссылкой на его значение в памяти.

    • object
    • array
    • function
    var foo = [1, 2],
        bar = foo;
    
    bar[0] = 9;
    
    console.log(foo[0], bar[0]); // => 9, 9.

    [⬆]

  • Для создания объекта используйте фигурные скобки. Не создавайте объекты через конструктор new Object.

    // плохо
    var item = new Object();
    
    // хорошо
    var item = {};
  • Не используйте зарезервированные слова в качестве ключей объектов. Они не будут работать в IE8. Подробнее

    // плохо
    var superman = {
      default: { clark: 'kent' },
      private: true
    };
    
    // хорошо
    var superman = {
      defaults: { clark: 'kent' },
      hidden: true
    };
  • Не используйте ключевые слова (в том числе измененные). Вместо них используйте синонимы.

    // плохо
    var superman = {
      class: 'alien'
    };
    
    // плохо
    var superman = {
      klass: 'alien'
    };
    
    // хорошо
    var superman = {
      type: 'alien'
    };

    [⬆]

  • Для создания массива используйте квадратные скобки. Не создавайте массивы через конструктор new Array.

    // плохо
    var items = new Array();
    
    // хорошо
    var items = [];
  • Если вы не знаете длину массива, используйте Array::push.

    var someStack = [];
    
    
    // плохо
    someStack[someStack.length] = 'abracadabra';
    
    // хорошо
    someStack.push('abracadabra');
  • Если вам необходимо скопировать массив, используйте Array::slice. jsPerf

    var len = items.length,
        itemsCopy = [],
        i;
    
    // плохо
    for (i = 0; i < len; i++) {
      itemsCopy[i] = items[i];
    }
    
    // хорошо
    itemsCopy = items.slice();
  • Чтобы скопировать похожий по свойствам на массив объект (например, NodeList или Arguments), используйте Array::slice.

    function trigger() {
      var args = Array.prototype.slice.call(arguments);
      ...
    }

    [⬆]

  • Используйте одинарные кавычки '' для строк.

    // плохо
    var name = "Боб Дилан";
    
    // хорошо
    var name = 'Боб Дилан';
    
    // плохо
    var fullName = "Боб " + this.lastName;
    
    // хорошо
    var fullName = 'Дилан ' + this.lastName;
  • Строки длиннее 80 символов нужно разделять, выполняя перенос через конкатенацию строк.

  • Осторожно: строки с большим количеством конкатенаций могут отрицательно влиять на быстродействие. jsPerf и Обсуждение

    // плохо
    var errorMessage = 'Эта сверхдлинная ошибка возникла из-за белой обезъяны. Не говори про обезъяну! Не слушай об обезьяне! Не думай об обезъяне!';
    
    // плохо
    var errorMessage = 'Эта сверхдлинная ошибка возникла из-за белой обезъяны. \
    Не говори про обезъяну! Не слушай об обезьяне! \
    Не думай об обезъяне!';
    
    // хорошо
    var errorMessage = 'Эта сверхдлинная ошибка возникла из-за белой обезъяны. ' +
      'Не говори про обезъяну! Не слушай об обезьяне! ' +
      'Не думай об обезъяне!';
  • Когда строка создается программным путем, используйте Array::join вместо объединения строк. В основном для IE: jsPerf.

    var items,
        messages,
        length,
        i;
    
    messages = [{
        state: 'success',
        message: 'Это работает.'
    },{
        state: 'success',
        message: 'Это тоже.'
    },{
        state: 'error',
        message: 'А я томат.'
    }];
    
    length = messages.length;
    
    // плохо
    function inbox(messages) {
      items = '<ul>';
    
      for (i = 0; i < length; i++) {
        items += '<li>' + messages[i].message + '</li>';
      }
    
      return items + '</ul>';
    }
    
    // хорошо
    function inbox(messages) {
      items = [];
    
      for (i = 0; i < length; i++) {
        items[i] = messages[i].message;
      }
    
      return '<ul><li>' + items.join('</li><li>') + '</li></ul>';
    }

    [⬆]

  • Объявление функций:

    // объявление анонимной функции
    var anonymous = function() {
      return true;
    };
    
    // объявление именованной функции
    var named = function named() {
      return true;
    };
    
    // объявление функции, которая сразу же выполняется (замыкание)
    (function() {
      console.log('Если вы читаете это, вы открыли консоль.');
    })();
  • Никогда не объявляйте функцию внутри блока кода — например в if, while, else и так далее. Единственное исключение — блок функции. Вместо этого присваивайте функцию уже объявленной через var переменной. Условное объявление функций работает, но в различных браузерах работает по-разному.

  • Примечание ECMA-262 устанавливает понятие блока как списка операторов. Объявление функции (не путайте с присвоением функции переменной) не является оператором. Комментарий по этому вопросу в ECMA-262.

    // плохо
    if (currentUser) {
      function test() {
        console.log('Плохой мальчик.');
      }
    }
    
    // хорошо
    var test;
    if (currentUser) {
      test = function test() {
        console.log('Молодец.');
      };
    }
  • Никогда не используйте аргумент функции arguments, он будет более приоритетным над объектом arguments, который доступен без объявления для каждой функции.

    // плохо
    function nope(name, options, arguments) {
      // ...код...
    }
    
    // хорошо
    function yup(name, options, args) {
      // ...код...
    }

    [⬆]

  • Используйте точечную нотацию для доступа к свойствам и методам.

    var luke = {
      jedi: true,
      age: 28
    };
    
    // плохо
    var isJedi = luke['jedi'];
    
    // хорошо
    var isJedi = luke.jedi;
  • Используйте нотацию с [], когда вы получаете свойство, имя для которого хранится в переменной.

    var luke = {
      jedi: true,
      age: 28
    };
    
    function getProp(prop) {
      return luke[prop];
    }
    
    var isJedi = getProp('jedi');

    [⬆]

  • Всегда используйте var для объявления переменных. В противном случае переменная будет объявлена глобальной. Загрязнение глобального пространства имен — всегда плохо.

    // плохо
    superPower = new SuperPower();
    
    // хорошо
    var superPower = new SuperPower();
  • Используйте одно var объявление переменных для всех переменных, и объявляйте каждую переменную на новой строке.

    // плохо
    var items = getItems();
    var goSportsTeam = true;
    var dragonball = 'z';
    
    // хорошо
    var items = getItems(),
        goSportsTeam = true,
        dragonball = 'z';
  • Объявляйте переменные, которым не присваивается значение, в конце. Это удобно, когда вам необходимо задать значение одной из этих переменных на базе уже присвоенных значений.

    // плохо
    var i, len, dragonball,
        items = getItems(),
        goSportsTeam = true;
    
    // плохо
    var i, items = getItems(),
        dragonball,
        goSportsTeam = true,
        len;
    
    // хорошо
    var items = getItems(),
        goSportsTeam = true,
        dragonball,
        length,
        i;
  • Присваивайте переменные в начале области видимости. Это помогает избегать проблем с объявлением переменных и областями видимости.

    // плохо
    function() {
      test();
      console.log('делаю что-нибудь..');
    
      //..или не делаю...
    
      var name = getName();
    
      if (name === 'test') {
        return false;
      }
    
      return name;
    }
    
    // хорошо
    function() {
      var name = getName();
    
      test();
      console.log('делаю что-то полезное..');
    
      //..продолжаю приносить пользу людям..
    
      if (name === 'test') {
        return false;
      }
    
      return name;
    }
    
    // плохо
    function() {
      var name = getName();
    
      if (!arguments.length) {
        return false;
      }
    
      return true;
    }
    
    // хорошо
    function() {
      if (!arguments.length) {
        return false;
      }
    
      var name = getName();
    
      return true;
    }

    [⬆]

  • Объявление переменных ограничивается областью видимости, а присвоение — нет.

    // Мы знаем, что это не будет работать
    // если нет глобальной переменной notDefined
    function example() {
      console.log(notDefined); // => выбрасывает код с ошибкой ReferenceError
    }
    
    // Декларирование переменной после ссылки на нее
    // не будет работать из-за ограничения области видимости.
    function example() {
      console.log(declaredButNotAssigned); // => undefined
      var declaredButNotAssigned = true;
    }
    
    // Интерпретатор переносит объявление переменной
    // к верху области видимости.
    // Что значит, что предыдущий пример в действительности
    // будет воспринят интерпретатором так:
    function example() {
      var declaredButNotAssigned;
      console.log(declaredButNotAssigned); // => undefined
      declaredButNotAssigned = true;
    }
  • Объявление анонимной функции поднимает наверх области видимости саму переменную, но не ее значение.

    function example() {
      console.log(anonymous); // => undefined
    
      anonymous(); // => TypeError anonymous is not a function
      // Ошибка типов: переменная anonymous не является функцией и не может быть вызвана
    
      var anonymous = function() {
        console.log('анонимная функция');
      };
    }
  • Именованные функции поднимают наверх области видимости переменную, не ее значение. Имя функции при этом недоступно в области видимости переменной и доступно только изнутри.

    function example() {
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
      // Ошибка типов: переменная named не является функцией и не может быть вызвана
    
      superPower(); // => ReferenceError superPower is not defined (Ошибка ссылки: переменная superPower не найдена в этой области видимости)
    
      var named = function superPower() {
        console.log('Я лечууууу');
      };
    }
    
    // То же самое происходит, когда имя функции и имя переменной совпадают.
    // var named доступно изнутри области видимости функции example.
    // function named доступна только изнутри ее самой.
    function example() {
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
      // Ошибка типов: переменная named не является функцией и не может быть вызвана
    
      var named = function named() {
        console.log('именованная функция');
      }
    }
  • Объявления функции поднимают на верх текущей области видимости и имя, и свое значение.

    function example() {
      superPower(); // => Я лечууууу
    
      function superPower() {
        console.log('Я лечууууу');
      }
    }
  • Более подробно можно прочитать в статье JavaScript Scoping & Hoisting от Ben Cherry

    [⬆]

  • Используйте === и !== вместо == и !=.

  • Условные выражения вычисляются посредством приведения к логическому типу Boolean через метод ToBoolean и всегда следуют следующим правилам:

    • Object всегда соответствует true
    • Undefined всегда соответствует false
    • Null всегда соответствует false
    • Boolean остается неизменным
    • Number соответствует false, если является +0, -0, или NaN, в противном случае соответствует true
    • String означает false, если является пустой строкой '', в противном случае true. Условно говоря, для строки происходит сравнение не ее самой, а ее длины – в соответствии с типом number.
    if ([0]) {
      // true
      // Массив(Array) является объектом, объекты преобразуются в true
    }
  • Используйте короткий синтаксис.

    // плохо
    if (name !== '') {
      // ...код...
    }
    
    // хорошо
    if (name) {
      // ...код...
    }
    
    // плохо
    if (collection.length > 0) {
      // ...код...
    }
    
    // хорошо
    if (collection.length) {
      // ...код...
    }
  • Более подробно можно прочитать в статье Truth Equality and JavaScript от Angus Croll

    [⬆]

  • Используйте фигурные скобки для всех многострочных блоков.

    // плохо
    if (test)
      return false;
    
    // хорошо
    if (test) return false;
    
    // хорошо
    if (test) {
      return false;
    }
    
    // плохо
    function() { return false; }
    
    // хорошо
    function() {
      return false;
    }

    [⬆]

  • Используйте /** ... */ для многострочных комментариев. Включите описание, опишите типы и значения для всех параметров и возвращаемых значений в формате jsdoc.

    // плохо
    // make() возвращает новый элемент
    // основываясь на получаемом имени тэга
    //
    // @param <String> tag
    // @return <Element> element
    function make(tag) {
    
      // ...создаем element...
    
      return element;
    }
    
    // хорошо
    /**
     * make() возвращает новый элемент
     * основываясь на получаемом имени тэга
     *
     * @param <String> tag
     * @return <Element> element
     */
    function make(tag) {
    
      // ...создаем element...
    
      return element;
    }
  • Используйте // для комментариев в одну строку. Размещайте комментарии на новой строке над темой комментария. Добавляйте пустую строку над комментарием.

    // плохо
    var active = true;  // устанавливаем активным элементом
    
    // хорошо
    // устанавливаем активным элементом
    var active = true;
    
    // плохо
    function getType() {
      console.log('проверяем тип...');
      // задаем тип по умолчанию 'no type'
      var type = this._type || 'no type';
    
      return type;
    }
    
    // хорошо
    function getType() {
      console.log('проверяем тип...');
    
      // задаем тип по умолчанию 'no type'
      var type = this._type || 'no type';
    
      return type;
    }
  • Префикс TODO помогает другим разработчикам быстро понять, что вы указываете на проблему, к которой нужно вернуться в дальнейшем, или если вы предлагете решение проблемы, которое должно быть реализовано. Эти комментарии отличаются от обычных комментариев, так как не описывают текущее поведение, а призывают к действию, например TODO -- нужно реализовать интерфейс. Такие комментарии также автоматически обнаруживаются многими IDE и редакторами кода, что позволяет быстро перемещаться между ними.

  • Используйте // TODO FIXME: для аннотирования проблем

    function Calculator() {
    
      // TODO FIXME: тут не нужно использовать глобальную переменную
      total = 0;
    
      return this;
    }
  • Используйте // TODO: для указания решений проблем

    function Calculator() {
    
      // TODO: должна быть возможность изменять значение через параметр функции
      this.total = 0;
    
      return this;
    }

    [⬆]

  • Используйте программную табуляцию (ее поддерживают все современные редакторы кода и IDE) из двух пробелов.

    // плохо
    function() {
    ∙∙∙∙var name;
    }
    
    // плохо
    function() {
    ∙var name;
    }
    
    // хорошо
    function() {
    ∙∙var name;
    }
  • Устанавливайте один пробел перед открывающей скобкой.

    // плохо
    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'
    });
  • Оставляйте новую строку в конце файла.

    // плохо
    (function(global) {
      // ...код...
    })(this);
    // хорошо
    (function(global) {
      // ...код...
    })(this);
  • Используйте отступы, когда делаете цепочки вызовов.

    // плохо
    $('#items').find('.selected').highlight().end().find('.open').updateCount();
    
    // хорошо
    $('#items')
      .find('.selected')
        .highlight()
        .end()
      .find('.open')
        .updateCount();
    
    // плохо
    var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true)
        .attr('width',  (radius + margin) * 2).append('svg:g')
        .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
        .call(tron.led);
    
    // хорошо
    var leds = stage.selectAll('.led')
        .data(data)
      .enter().append('svg:svg')
        .class('led', true)
        .attr('width',  (radius + margin) * 2)
      .append('svg:g')
        .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
        .call(tron.led);

    [⬆]

  • Запятые в начале строки: Нет.

    // плохо
    var once
      , upon
      , aTime;
    
    // хорошо
    var once,
        upon,
        aTime;
    
    // плохо
    var hero = {
        firstName: 'Bob'
      , lastName: 'Parr'
      , heroName: 'Mr. Incredible'
      , superPower: 'strength'
    };
    
    // хорошо
    var hero = {
      firstName: 'Bob',
      lastName: 'Parr',
      heroName: 'Mr. Incredible',
      superPower: 'strength'
    };
  • Дополнительная запятая в конце объектов: Нет. Она способна вызвать проблемы с IE6/7 и IE9 в режиме совместимости. В некоторых реализациях ES3 запятая в конце массива увеличивает его длину на 1, что может вызвать проблемы. Этот вопрос был прояснен только в ES5 (оригинал):

Редакция ECMAScript 5 однозначно устанавливает факт, что запятая в конце ArrayInitialiser не должна увеличивать длину массива. Это несемантическое изменение от Редакции ECMAScript 3, но некоторые реализации до этого некорректно разрешали этот вопрос.

  // плохо
  var hero = {
    firstName: 'Kevin',
    lastName: 'Flynn',
  };

  var heroes = [
    'Batman',
    'Superman',
  ];

  // хорошо
  var hero = {
    firstName: 'Kevin',
    lastName: 'Flynn'
  };

  var heroes = [
    'Batman',
    'Superman'
  ];

[⬆]

  • Да.

    // плохо
    (function() {
      var name = 'Skywalker'
      return name
    })()
    
    // хорошо
    (function() {
      var name = 'Skywalker';
      return name;
    })();
    
    // хорошо
    ;(function() {
      var name = 'Skywalker';
      return name;
    })();

    [⬆]

  • Выполняйте приведение типов в начале операции, но не делайте его избыточным.

  • Строки:

    //  => this.reviewScore = 9;
    
    // плохо
    var totalScore = this.reviewScore + '';
    
    // хорошо
    var totalScore = '' + this.reviewScore;
    
    // плохо
    var totalScore = '' + this.reviewScore + ' итого';
    
    // хорошо
    var totalScore = this.reviewScore + ' итого';
  • Используйте parseInt для чисел и всегда указывайте основание для приведения типов.

    var inputValue = '4';
    
    // плохо
    var val = new Number(inputValue);
    
    // плохо
    var val = +inputValue;
    
    // плохо
    var val = inputValue >> 0;
    
    // плохо
    var val = parseInt(inputValue);
    
    // хорошо
    var val = Number(inputValue);
    
    // хорошо
    var val = parseInt(inputValue, 10);
  • Если по какой-либо причине вы делаете что-то дикое, и именно на parseInt тратится больше всего ресурсов, используйте побитовый сдвиг из соображений быстродействия, но обязательно оставьте комментарий с объяснением причин.

    // хорошо
    /**
     * этот код медленно работал из-за parseInt
     * побитовый сдвиг строки для приведения ее к числу
     * работает значительно быстрее.
     */
    var val = inputValue >> 0;
  • Примечание: Будьте осторожны с побитовыми операциями. Числа в JavaScript являются 64-битными значениями, но побитовые операции всегда возвращают 32-битные значенения. Источник. Побитовые операции над числами, значение которых выходит за 32 бита (верхний предел: 2,147,483,647).

    2147483647 >> 0 //=> 2147483647
    2147483648 >> 0 //=> -2147483648
    2147483649 >> 0 //=> -2147483647
    
  • логические типы(Boolean):

    var age = 0;
    
    // плохо
    var hasAge = new Boolean(age);
    
    // хорошо
    var hasAge = Boolean(age);
    
    // хорошо
    var hasAge = !!age;

    [⬆]

  • Избегайте однобуквенных имен функций. Имена должны давать представление о том, что делает эта функция.

    // плохо
    function q() {
      // ...код...
    }
    
    // хорошо
    function query() {
      // ...код...
    }
  • Используйте camelCase для именования объектов, функций и переменных.

    // плохо
    var OBJEcttsssss = {};
    var this_is_my_object = {};
    function c() {};
    var u = new user({
      name: 'Bob Parr'
    });
    
    // хорошо
    var thisIsMyObject = {};
    function thisIsMyFunction() {};
    var user = new User({
      name: 'Bob Parr'
    });
  • Используйте PascalCase для именования конструкторов классов

    // плохо
    function user(options) {
      this.name = options.name;
    }
    
    var bad = new user({
      name: 'Плохиш'
    });
    
    // хорошо
    function User(options) {
      this.name = options.name;
    }
    
    var good = new User({
      name: 'Кибальчиш'
    });
  • Используйте подчеркивание _ в качестве префикса для именования внутренних методов и переменных объекта.

    // плохо
    this.__firstName__ = 'Panda';
    this.firstName_ = 'Panda';
    
    // хорошо
    this._firstName = 'Panda';
  • Создавая ссылку на this, используйте _this.

    // плохо
    function() {
      var self = this;
      return function() {
        console.log(self);
      };
    }
    
    // плохо
    function() {
      var that = this;
      return function() {
        console.log(that);
      };
    }
    
    // хорошо
    function() {
      var _this = this;
      return function() {
        console.log(_this);
      };
    }
  • Задавайте имена для функций. Это повышает читаемость сообщений об ошибках кода.

    // плохо
    var log = function(msg) {
      console.log(msg);
    };
    
    // хорошо
    var log = function log(msg) {
      console.log(msg);
    };

    [⬆]

  • Функции универсального доступа к свойствам не требуются

  • Если вам необходимо создать функцию для доступа к переменной, используйте раздельные функции getVal() и setVal('hello')

    // плохо
    dragon.age();
    
    // хорошо
    dragon.getAge();
    
    // плохо
    dragon.age(25);
    
    // хорошо
    dragon.setAge(25);
  • Если свойство является логическим(boolean), используйте isVal() или hasVal()

    // плохо
    if (!dragon.age()) {
      return false;
    }
    
    // хорошо
    if (!dragon.hasAge()) {
      return false;
    }
  • Вы можете создавать функции get() и set(), но будьте логичны и последовательны – то есть не добавляйте свойства, которые не могут быть изменены через эти функции.

    function Jedi(options) {
      options || (options = {});
      var lightsaber = options.lightsaber || 'blue';
      this.set('lightsaber', lightsaber);
    }
    
    Jedi.prototype.set = function(key, val) {
      this[key] = val;
    };
    
    Jedi.prototype.get = function(key) {
      return this[key];
    };

    [⬆]

  • Присваивайте метод прототипу вместо замены прототипа на другой объект. Замена прототипа на другой объект делает наследование невозможным.

    function Jedi() {
      console.log('new jedi');
    }
    
    // плохо
    Jedi.prototype = {
      fight: function fight() {
        console.log('fighting');
      },
    
      block: function block() {
        console.log('blocking');
      }
    };
    
    // хорошо
    Jedi.prototype.fight = function fight() {
      console.log('fighting');
    };
    
    Jedi.prototype.block = function block() {
      console.log('blocking');
    };
  • Методы могут возвращать this для создания цепочек вызовов. Но стоит оставаться последовательным и обеспечить одинаковое поведение для всех методов, кроме геттеров.

    // плохо
    Jedi.prototype.jump = function() {
      this.jumping = true;
      return true;
    };
    
    Jedi.prototype.setHeight = function(height) {
      this.height = height;
    };
    
    var luke = new Jedi();
    luke.jump(); // => true
    luke.setHeight(20) // => undefined
    
    // хорошо
    Jedi.prototype.jump = function() {
      this.jumping = true;
      return this;
    };
    
    Jedi.prototype.setHeight = function(height) {
      this.height = height;
      return this;
    };
    
    var luke = new Jedi();
    
    luke.jump()
      .setHeight(20);
  • Вы можете заменить стандартный метод toString(), но убедитесь, что он работает и не вызывает побочных эффектов.

    function Jedi(options) {
      options || (options = {});
      this.name = options.name || 'no name';
    }
    
    Jedi.prototype.getName = function getName() {
      return this.name;
    };
    
    Jedi.prototype.toString = function toString() {
      return 'Jedi - ' + this.getName();
    };

    [⬆]

  • Подключая набор данных к событиям (как DOM-событиям, так и js-событиям, например, в Backbone), передавайте объект вместо простой переменной. Это позволяет в процессе всплытия событий добавлять к данному объекту дополнительную информацию.

    // плохо
    $(this).trigger('listingUpdated', listing.id);
    
    ...
    
    $(this).on('listingUpdated', function(e, listing) {
         //делаем что-нибудь с listing, например:
         listing.name = listings[listing.id]
    });

    prefer:

    // хорошо
    $(this).trigger('listingUpdated', { listingId : listing.id });
    
    ...
    
    $(this).on('listingUpdated', function(e, data) {
      // делаем что-нибудь с data.listingId
    });

[⬆]

  • Модуль должен начинаться с !. За счет этого даже некорректно сформированный модуль, в конце которого отсутствует точка с запятой, не вызовет ошибок при автоматической сборке скриптов. Объяснение

  • Файл должен быть именован с camelCase, находиться в папке с тем же именем, и совпадать с именем экспортируемой переменной.

  • Добавьте метод noConflict(), устанавливающий экспортируемый модуль в состояние предыдущей версии.

  • Всегда объявляйте 'use strict'; в начале модуля.

    // fancyInput/fancyInput.js
    
    !function(global) {
      'use strict';
    
      var previousFancyInput = global.FancyInput;
    
      function FancyInput(options) {
        this.options = options || {};
      }
    
      FancyInput.noConflict = function noConflict() {
        global.FancyInput = previousFancyInput;
        return FancyInput;
      };
    
      global.FancyInput = FancyInput;
    }(this);

    [⬆]

  • Для jQuery-переменных используйте префикс $.

    // плохо
    var sidebar = $('.sidebar');
    
    // хорошо
    var $sidebar = $('.sidebar');
  • Кэшируйте jQuery-запросы. Каждый новый jQuery-запрос делает повторный поиск по DOM-дереву, и приложение начинает работать медленнее.

    // плохо
    function setSidebar() {
      $('.sidebar').hide();
    
      // ...код...
    
      $('.sidebar').css({
        'background-color': 'pink'
      });
    }
    
    // хорошо
    function setSidebar() {
      var $sidebar = $('.sidebar');
      $sidebar.hide();
    
      // ...код...
    
      $sidebar.css({
        'background-color': 'pink'
      });
    }
  • Для DOM-запросов используйте классический каскадный CSS-синтаксис $('.sidebar ul') или родитель > потомок $('.sidebar > ul'). jsPerf

  • Используйте find для поиска внутри DOM-объекта.

    // плохо
    $('ul', '.sidebar').hide();
    
    // плохо
    $('.sidebar').find('ul').hide();
    
    // хорошо
    $('.sidebar ul').hide();
    
    // хорошо
    $('.sidebar > ul').hide();
    
    // хорошо
    $sidebar.find('ul');

    [⬆]

[⬆]

  • Да.

    function() {
      return true;
    }

    [⬆]

[⬆]

Прочитайте это

Другие руководства по стилю

Другие стили

Дальнейшее прочтение

Книги

Блоги

[⬆]

Вот неполный список организаций, которые опираются на оригинальное руководство от AirBnB. Если вы собираетесь использовать это переведенное руководство, сделайте pull request, и мы сможем начать отдельный список компаний, использующих данный перевод.

Это руководство так же переведено на:

(The MIT License)

Copyright (c) 2012 Airbnb: оригинальный текст, (c) 2013 Uprock: перевод

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[⬆]

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published