#поговорим_за_frontend


    Javascript patterns & Чистый код

    Эпизод 1: Скрытая угроза

    • Чистый код
    • Javascript Patterns (в следующей серии)

    Чистый код

    Фразы-паразиты

    • мне мой код понятен. (с)
    • и так работает. (с)
    • мы никогда не будем вносить сюда изменения. (с)
    • потом перепишу. (с)

    ∞

    Нейминг

    1. Никаких сокращений

                  
                    // Плохо
                    const frmt = 'dd-mm-yyyy';
                    const string = ' Упс!';
                    const page = 5;
    
                    const names = users.map((i) => i.firstName + i.lastName );
                  
                   
                  
                    // Хорошо
                    const dateFormat = 'dd-mm-yyyy';
                    const errorTitle = ' Упс!';
                    const currentPage = 5;
    
                    const fullNames = users.map((user) =>
                      user.firstName + user.lastName
                    );
                  
                  

    2. Типы и классы начинаются с большой буквы

    3. Никаких T/I

                   
                    // Плохо
                    type user = {id: string};
                    type TUser = {id: string};
                    interface IMovie = {id: string};
                  
                
                   
                    // Хорошо
                    type User = {id: string};
                    interface Movie = {id: string};
                  
                

    4. Функции должны начинаться с глаголов

                   
                     // Плохо:
                    function filteredUsers = (users) => users.filter(...)
                     👆// это переменная или функция?
    
                    // Хорошо:
                    function filterUsers = (users) => users.filter(...)
                    function getFilteredUsers = (users) => users.filter(...)
                   
                

    Нейминг переменной может содержать префиксы
    (is-/has-/should-/can-)

                   
                     // Плохо:
                      const disabled = false;
                      const notAvailableForEditing = true;
                     // 👆пока прочитаешь переменную уже состаришься
                      const areProductsPresent = true;
    
                      // Хорошо:
                      const isDisabled = false;
                      const isEnabled = true;
    
                      const canEdit = false;
                      const hasProducts = true;
                   
                

    Нейминг должен учитывать единственное/множественное число

                   
                     // Плохо:
                    id.forEach((i) => console.log(i));
                    // только по forEach стало понятно что здесь множество id
    
                    // Хорошо:
                    ids.forEach((id) => console.log(id));
                    // теперь переменная говорит нам о том, что это множество
                    // внутри цикла можно использовать единственное число вместо сокращения
                   
                

    Объекты

    Всё в Javascript - это объекты

    Замена switch и if

                  
                    let value = 2 + 2;
    
                    switch (value) {
                      case 3:
                        alert( 'Маловато' ); break;
                      case 4:
                        alert( 'В точку!' ); break;
                      case 5:
                        alert( 'Перебор' ); break;
                      default:
                        alert( "Нет таких значений" );
                    }
                  
                  
                  
                    const titles = {
                      3: 'Маловато',
                      4: 'В точку!',
                      5: 'Перебор'
                    }
    
                    const value = 2 + 2;
                    const title = titles[value] || 'Нет таких значений'.
    
                  
                

    Условный рендеринг

    Функции

    1. Одна функция - одно действие

                  
                    const users = [
                      {id: 1, age: 12}, {id: 2, age: 15},
                      {id: 3, age: 18}, {id: 4, age: 13},
                    ];
    
                    const calculateAndShowAverageAge = (users) => {
                      if (users.length === 0){
                        return 0;
                      }
    
                      let sum = 0;
                      for (let i = 0; i< users.length; i++) {
                        sum += users[i].age;
                      }
    
                      const average = Math.floor(sum / users.length);
                      alert(`Средний возраст посетителей: ${average}`);
                    };
    
                    calculateAndShowAverageAge(users);
                    // alert(Средний возраст посетителей: 14);
                  
                  
                     
                       const orders = [
                        {id: 1, value: 100}, {id: 2, value: 110},
                        {id: 3, value: 200}, {id: 4, value: 150}
                        ];
    
                        const calculateAndShowAverageOrderValue = (orders) => {
                            if (orders.length === 0){
                                return 0;
                            }
                            let sum = 0;
                            for (let i = 0; i< orders.length; i++) {
                                sum += orders[i].value;
                            }
    
                            const average = Math.floor(sum / orders.length);
                                alert(`Средняя стоимость заказов: ${average}`);
                        };
    
                        calculateAndShowAverageOrderValue(orders);
                        // alert(Средняя стоимость заказов: 140);
                     
                  
                     
                       const calculateAverage = (values) => {
                        if (values.length === 0){
                            return 0;
                        }
    
                        let sum = 0;
                        values.forEach(value => sum += value);
                        return Math.floor(sum / values.length);
                    };
    
                    const averageAge = calculateAverage(users.map(({age}) => age));
                    const averageOrdersValue = calculateAverage(orders.map(({value}) => value));
    
                    alert(`Средний возраст посетителей: ${averageAge}`);
                    alert(`Средняя стоимость заказов: ${averageOrdersValue}`);
                     
                  

    2. Старайтесь писать чистые функции

    Правила чистой функции

    • Не имеет побочных эффектов (api, console и пр.)
    • Сколько раз ни вызови - один результат
    • Не мутирует данные
    • Не зависит от внешних данных
                     
                       const DISCOUNT = 15;
    
                       const calculateDiscount = (cost) => cost * (100 - DISCOUNT);
                     
                
                     
                       const generateID = () => Math.floor(Math.random() * 10000);
    
                       console.log(generateID()); // 7602
                       console.log(generateID()); // 7131
                     
                  
                     
                       let id = 0;
                       const createPerson = name => ({ id: ++id, name});
    
                       console.log(createPerson("Биба")); // {id: 1, name: "Биба"}
                       console.log(createPerson("Боба")); // {id: 2, name: "Боба"}
                     
                  

    3. Количество аргументов и размер

    Количество аргументов - не более 7
    Размер ~ чтобы влазило в экран или не более 100 строк

    If-ы

    1. Старайтесь избегать больших вложенностей

    2. Обрабатывайте исключения в начале

                     
                       const getAnyResult = (array: string[]) => {
                         if ... do any
                         if ... do any
                         if ... do any
    
                         if (array.length === 0){
                           return []
                         }
                       }
                     
                  
                     
                       const getAnyResult = (array: string[]) => {
                         if (array.length === 0){
                           return []
                         }
    
                         if ... do any
                         if ... do any
                         if ... do any
                       }
                     
                  

    Комментарии

    Комментарии к коду - это извинение/оправдание перед собой или другими разработчиками
                     
                      // оно ужасно, но не трогаем чтобы не сломать
                      // быстрый хак для релиза, потом сделаем хорошо
    
                      // @ts-ignore
                      // eslint-disable-next-line
    
                      // https://stackoverflow.com/questions/7616461
                     
                  
    https://skillbox.ru/media/code/zabavnye-kommentarii-v-kode/

    Полезные комментарии

                     
                       // TODO: remove sx props
                       // TODO: refactor it in JIRA-1999
                     
                    

    Что почитать

    • Стив Макконнелл: Совершенный код (часть 2-4)
    • Google JavaScript Style Guide
    • Алексей Золотых: Борьба с ветрянными мельницами, или Как жить с техническим долгом (HolyJS 2023 Spring)
    • https://skillbox.ru/media/code/zabavnye-kommentarii-v-kode/