Перевод книги Райана Макдермота clean-code-javascript.

Оглавление:



image

Используйте значимые и произносимые имена переменных


Плохо:

const yyyymmdstr = moment().format('YYYY/MM/DD');

Хорошо:

const yearMonthDay = moment().format('YYYY/MM/DD');

Используйте один и тот же метод для того же типа переменной


Плохо:

getUserInfo();
getClientData();
getCustomerRecord();

Хорошо:

getUser();

Используйте именованные значения


Мы будем читать код чаще, чем мы когда-нибудь напишем. Важно писать читаемый код, который легко искать. Делайте ваши имена для поиска. Такие инструменты, как buddy.js и ESLint могут помочь идентифицировать неназванные константы.

Плохо:

// Что значит 86400000?
setTimeout(blastOff, 86400000);

Хорошо:

// Объявляйте их как глобальные переменные.
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);

Используйте объясняющие переменные


Плохо:

const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(
    address.match(cityZipCodeRegex)[1], 
    address.match(cityZipCodeRegex)[2]
);

Хорошо:

const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

Используйте очеловеченные названия


Явное лучше, чем неявное.

Плохо:

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  // Что значит `l`?
  dispatch(l);
});

Хорошо:

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  dispatch(location);
});

Не добавляйте ненужный контекст


Если ваше имя класса / объекта говорит вам что это, не повторяйте тоже при именовании его свойств и методов.

Плохо:

const car = {
  carMake: 'Honda',
  carModel: 'Accord',
  carColor: 'Blue'
};

function paintCar(car) {
  car.carColor = 'Red';
}

Хорошо:

const car = {
  make: 'Honda',
  model: 'Accord',
  color: 'Blue'
};

function paintCar(car) {
  car.color = 'Red';
}

Используйте условия по умолчанию вместо коротких замыканий или условных выражений


Плохо:

function createMicrobrewery(name) {
  const breweryName = name || 'Hipster Brew Co.';
  // ...
}

Хорошо:

function createMicrobrewery(breweryName = 'Hipster Brew Co.') {
  // ...
}
Поделиться с друзьями
-->

Комментарии (36)


  1. leremin
    14.01.2017 12:02
    +4

    Это относится ко всем языкам программирования всех времен и народов.


    1. BoryaMogila
      14.01.2017 12:07

      Полностью с вами согласен.


      1. leremin
        14.01.2017 12:47

        Но тогда зачем писать очевидные вещи, которым место в «Программирование для самых маленьких (в картинках)»? Да и полно подобных статей уже.


        1. lair
          14.01.2017 13:44
          +1

          Читайте оригинал.


    1. Tishka17
      15.01.2017 13:45

      И даже для SQL? А то у наших датабазистов совсем другие соглашения об именовании


  1. vmb
    14.01.2017 13:16
    +6

    Наверное, вам стоит подписаться на коммиты в репозитории, потому что примеры и формулировки там сейчас активно и коллективно обновляются. Например, этот код уже отличается от старой версии, использованной вами.


    1. DistortNeo
      15.01.2017 04:56
      +1

      Да, так гораздо интереснее. Кстати, один момент мне не очень понравился, который заявлен как Good:

      const totalOutput = programmerOutput
        .map((programmer) => programmer.linesOfCode)
        .reduce((acc, linesOfCode) => acc + linesOfCode, 0);
      

      Вместо крокодила reduce здесь логичнее просто написать sum(). Иначе вариант с циклом мне нравится больше.


  1. mopsicus
    14.01.2017 13:28
    +10

    Лучше объедините переводы в одну статью. Читать отдельные короткие, не очень удобно.


    1. sshikov
      14.01.2017 15:20
      +7

      +1. Введение — вообще ни о чем. Эта часть — коротковата. Если материал уже есть — лучше чуть подлиннее. При наличии нормальной структуры будет читаться лучше.

      К React, Node, Angular это точно имеет отношение?


  1. hosembafer
    14.01.2017 17:38
    +1

    function createMicrobrewery(breweryName = 'Hipster Brew Co.') {
    //…
    }

    Узнал для себя новое, и давно уже значение по умолчанию доступно в JS?


    1. JIghtuse
      14.01.2017 17:44
      +2

      Согласно MDN, начиная с ES6.


  1. Jofr
    14.01.2017 21:56
    +1

    Вы уж простите, я понимаю, что этому место в личке, но качество перевода — ужасное. Везде сквозит калькирование английской грамматики. Абзац после заголовка «Используйте именованные значения» — вообще кошмар.

    Если решитесь продолжать — готов помочь с вычиткой и корректурой, мне не сложно.


    1. BoryaMogila
      15.01.2017 16:10

      Это мой первый перевод, согласен с вами по поводу качества. Буду старатся исправится.


  1. 404
    15.01.2017 00:35
    +1

    Автор книги «Чистый код» — Роберт Мартин. А Раян Макдермот сделал адаптацию не всей книги, а последней главы.


  1. lany
    15.01.2017 07:13
    -2

    const address = 'One Infinite Loop, Cupertino 95014';
    const cityStateRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
    const [, city, state] = address.match(cityStateRegex);
    saveCityState(city, state);

    Что-то лютый ад. Это хороший код? Про инкапсуляцию и переиспользование ничего не слышали? Хороший код выглядит как-то так:


    const Address = require('address');
    
    const addressText = 'One Infinite Loop, Cupertino 95014';
    const address = Address.parse(addressText);
    saveCityState(address.city, address.state);

    И адский регексп должен быть спрятан внутрь реализации Address.parse. Нет ничего хуже раскиданных по бизнес-логике регекспов. Что вы будете делать, если в другом компоненте потребуется парсить адреса? И завтра окажется, что одним регекспом произвольно записанные адреса не парсятся, нужна какая-нибудь условная логика. Тогда удачи вам в рефакторинге.


    1. andreysmind
      15.01.2017 15:59
      +2

      Тссс, если они все в одной статье расскажут, то как потом деньги зарабатывать?


      1. lany
        15.01.2017 16:17

        Всегда можно подобрать нормальный пример, который не будет требовать знаний из следующих глав. В крайнем случае написать не "хорошо", а "лучше, но всё равно плохо, а вот почему — смотрите главу 10, которую можно приобрести за отдельные деньги". Люди же читают это и потом реально плодят такой ужас прикрываясь тем, что кто-то над таким кодом написал "хорошо".


        1. andreysmind
          15.01.2017 16:25
          +1

          Для этого у людей должен быть «боевой» опыт разработки и желательно в команде. У большинства пишущих такие статьи есть только личные проекты, статьи о том как надо писать правильно и список авторитетных статей и книг которые прочитаны и бездумно применяются.


          1. lany
            15.01.2017 16:41

            Тут не могу не согласиться.


    1. murzilka
      18.01.2017 16:15
      +1

      const Address = require('address');
      


      Больше модулей богу модулей!

      P.S. В исходном плохом варианте куда больше убило два одинаковых вызова
      address.match
      

      Вот это действительно ужасно.


      1. lany
        19.01.2017 07:06
        -1

        Вы так говорите будто структурированный код — это что-то плохое. Должно быть вы веб-приложения в одной HTML-ке пишете, вставляя прямо в неё секции style и script?


        1. murzilka
          19.01.2017 15:18
          +2

          Это как вы такой вывод сделали? Мне просто любопытно логическую цепочку проследить.

          Как из моих замечаний о том, что
          1 — выделять один регэксп в модуль это перебор
          2 — вызывать в одной строке кода два раза match для одной и той же строки это тоже перебор

          вы сделали вывод о том, что я весь код пишу в html?


  1. longclaps
    15.01.2017 11:08
    +1

    Car = {
     make: 'Honda',
    

    'Honda' — это brand, дружище…


    1. lany
      15.01.2017 13:49

      maker, видимо, имелось в виду. Производитель то бишь.


      1. longclaps
        15.01.2017 14:37

        И эти люди запрещают ковырять в носу учат, как выбирать идентификаторы…


    1. Maccimo
      15.01.2017 18:49
      +1

      make

      noun

      1 The manufacturer or trade name of a product

      https://en.oxforddictionaries.com/definition/make


      1. justboris
        15.01.2017 23:21

        Даже если это написано в Оксфордском словаре, это еще не значит, что надо так писать.


        Brand намного более понятнее, и не надо каждому читающему этот код бегать в словарь, чтобы понять, что имел в виду автор.


  1. andreysmind
    15.01.2017 15:56
    +2

    const locations = ['Austin', 'New York', 'San Francisco'];
    locations.forEach((location) => {
      doStuff();
      doSomeOtherStuff();
      // ...
      // ...
      // ...
      dispatch(location);
    });
    

    А что случилось с правилами «Не делать длинные функции» и «forEach на 95% медленнее for»? Все, уже не модные на этой неделе?


    1. justboris
      15.01.2017 23:37

      А откуда цифра 95%?


      Вроде же медленнее, но не настолько.


      1. andreysmind
        16.01.2017 10:41

        Да в какой-то статье приводились цифры
        https://coderwall.com/p/kvzbpa/don-t-use-array-foreach-use-for-instead


        1. justboris
          16.01.2017 11:18
          +1

          Очень странная статья. Попробовал воспроизвести их тесты у себя локально в Node.js — получилось 50% максимум, но не 95%.


          Попробуйте и вы, интересно, что получится


          https://gist.github.com/just-boris/d05c41507167f4dcc09ccc8bed547207


          1. andreysmind
            16.01.2017 11:19

            спасибо! попробую.


        1. justboris
          16.01.2017 11:21

          И вообще, "производительность" и "мода" в одном предложении не складываются. Движки развиваются, и надо регулярно перепроверять информацию, устаревает буквально с каждым новым релизом браузеров.


  1. Alkon410
    15.01.2017 16:05

    никто мне не указ, я сам определяю, из какого дерева делать костыли.


  1. ArsenAbakarov
    16.01.2017 00:37

    Просто почитать «Совершенный код» от автора Макконнелл


  1. MarcusAurelius
    23.01.2017 16:28
    +1

    Это плохо: const Car = { ... };
    Это хорошо: const car = { ... };
    Объекты называем в lowerCamelCase, а классы и конструкторы прототипов в UpperCamelCase.