W tym artykule Joachim Zeelmaekers – programista JavaScript, omówi niektóre zasady, które możesz zastosować, aby ulepszyć swój kod. Wszystkie przykłady dotyczą JavaScript.

Czytelny kod to kod możliwy do utrzymania

Uważam, że kod czytelny to kod możliwy do utrzymania. Celem każdego programisty jest napisanie kodu wysokiej jakości. Każdy programista w zespole, niezależnie od swojego poziomu umiejętności, musi być w stanie zrozumieć kod, czytając go. Jest to bardzo pomocne, w szczególności dla młodych programistów, do nabrania większej pewności w pisaniu kodu.

Usuń niepotrzebne komentarze

Oczywiście część kodu może być bardzo złożona. Wiem o tym i widziałem to wiele razy. Tutaj dodałbym odpowiednią dokumentację i komentarze do kodu.

Nie zrozum mnie źle. Nie jestem fanem komentarzy do kodu lub JavaScript JSdoc. A przynajmniej nie tak długo, dopóki ich nie potrzebuję. 😉

Nie potrzebuję żadnych komentarzy, aby przeczytać, że ta funkcja pobiera X tablic i łączy je w nową tablicę.

function mergeArrays(…arrays) {

  let mergedArray = []

  arrays.forEach(array => {

      mergedArray = […mergedArray, …array]

  })

  return mergedArray

}

Dodanie JSdoc do tego kodu nie poprawi jego czytelności. Spodziewam się, że członkowie mojego zespołu wiedzą, czym jest spread operator. A jeśli nie, powinni zapytać o to podczas jego przeglądania.

I nie zapominajmy o skomentowanych code bloks. Jest tylko jedno rozwiązanie: USUŃ TEN KOD. Git ma niesamowitą funkcję pobierania starego kodu, więc po co zostawiać to w komentarzach?

Proszę, przestań robić złomowisko ze swojej bazy kodów.

Skoncentruj się na nazewnictwie

Jeśli spojrzysz na nazwę mergeArrays, od razu powinno być zrozumiałe, że ta funkcja łączy liczbę X tablic w nową.

Wiem, że nazwanie rzeczy jest trudne. Im bardziej złożona jest funkcja, tym trudniejsze będzie jej nazewnictwo… W tym celu używam pewnej reguły, która mi to ułatwia. Oto jak to robię.

Wyobraź sobie funkcję, która łączy 2 tablice liczb i generuje nową unikalną listę liczb. Jak byś to nazwał? Może coś takiego?

function mergeNumberListIntoUniqueList(listOne, listTwo) {
  return [...new Set([...listOne, ...listTwo])]
}

Nazwa nie jest taka zła, ponieważ robi to, co mówi. Problem w tym, że funkcja robi 2 rzeczy. Im więcej dana funkcja robi rzeczy, tym trudniej jest ją nazwać. Wyodrębnienie  kodu do 2 oddzielnych funkcji sprawi, że będzie on po pierwsze o wiele łatwiejszy, a po drugie będzie go można wielokrotnie używać w tym samym czasie.

function mergeLists(listOne, listTwo) {
  return [...listOne, ...listTwo]
}
function createUniqueList(list) {
  return [...new Set(list)]
}

Oczywiście łatwo jest stworzyć oneliner bez wywoływania nowej funkcji. Ale czasami oneliners nie jest, aż tak czytelny.

If statements

Nie mogłem znaleźć nazwy dla tego problemu … Zobacz! Nazwanie jest trudne …

Ale często to widzę.

Problem

if(value === 'duck' || value === 'dog' || value === 'cat') {
  // ...
}

Rozwiązanie

const options = ['duck', 'dog', 'cat'];
if (options.includes(value)) {
  // ...
}

W ten sposób utworzysz czytelny fragment kodu, który wygląda jak angielskie zdanie.

Jeśli opcje zawierają wartość, to …

Early exit

Istnieje kilkanaście sposobów na nazwanie tej zasady, ale wybrałem nazwę „Early exit”.

Pozwól, że pokażę Tobie fragment kodu. Jestem pewien, że widziałeś już coś takiego wcześniej.

function handleEvent(event) {
  if (event) {
    const target = event.target;
    if (target) {
      // Your awesome piece of code that uses target
    }
  }
}

Tutaj próbujemy sprawdzić, czy object event istnieje, a własność target jest dostępna. Problem polega na tym, że używamy już 2 instrukcji if.

Zobaczmy, jak możesz tutaj zrobić „Early exit”.

function handleEvent(event) {
  if (!event || !event.target) {
    return;
  }
  // Your awesome piece of code that uses target
}

Stosując tutaj „Early exit”, sprawdzasz, czy event i event.target istnieją. Od razu można zauważyć, że event.target nie jest fałszywe. Jasne jest także, że żaden inny kod nie jest wykonywany, jeśli ta instrukcja jest fałszywa.

Cesja niszcząca

W javascript możemy restrukturyzować obiekty i tablice.

Zgodnie z dokumentacją znajdującą się na developer.mozilla.org, składnia przypisania restrukturyzacji jest wyrażeniem JavaScript, które umożliwia rozpakowywanie wartości z tablic lub właściwości z obiektów do odrębnych zmiennych.

Niektóre przykłady kodu

// Destructuring an object
const numbers = {one: 1, two: 2};
const {one, two} = numbers;
console.log(one); // 1
console.log(two); // 2
// Destructuring an array
const numbers = [1, 2, 3, 4, 5];
const [one, two] = numbers;
console.log(one); // 1
console.log(two); // 2

Problem z restrukturyzacją polega na tym, że czasami tworzy złą nazwę dla właściwości. Doskonałym przykładem jest pobieranie danych z API i otrzymywanie obiektu, który posiada właściwości data.

const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name} = response.data

Ten przykładowy kod wskazuje, że pobierasz organizatora o ID 1. Obiekt organizer ma nazwę i przenosisz ją. Nic w tym złego.

Ten kod działa i jest w porządku. Ale dlaczego ta nazwa nadal jest nazwą? Czy będzie to jedyna właściwość w całym zakresie? A od jakiego obiektu jest znowu ta nazwa?

Unikaj tych pytań, przypisując nazwę właściwości.

const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name: organizerName} = response.data

Ten kod staje się bardziej czytelny. Każdy będzie wiedział, że zmienną jest nazwa organizatora.

Zasada harcerza

Słyszałeś kiedyś o wyrażeniu: „Uczyń to lepszym, niż to co zobaczyłeś”?

Cóż, dokładnie taka jest zasada harcerza. Uczyń to lepszym, niż to zobaczyłeś. Czy znalazłeś code smell? Refaktoryzuj to! Czy znalazłeś nieużywaną zmienną? Usunąć ją!

Lubię to porównywać z sytuacją związaną ze sprzątaniem pokoju. Wyobraźmy sobie, że wszyscy w Twoim domu zostawiają naczynia w zlewie, wyrzucają śmieci na korytarz, a pranie zostawiają w łazience. Ale w każdą niedzielę trzeba posprzątać cały dom i zajmuje to grubo ponad 4 godziny. Chciałbyś tego?

Jestem pewien, że odpowiedź brzmi nie. Jeśli więc wszyscy od razu będą dbać o porządek, w niedzielę będzie mniej pracy.

To samo dotyczy baz kodów. Jeśli każdy mały code smell pozostanie w bazie kodu, nikt nie usunie nieużywanych zmiennych, linter oszaleje i będzie miał około 77 ostrzeżeń. Wtedy będzie dużo sprzątania, natomiast jeśli każdy weźmie na siebie odpowiedzialność i zastosuje zasadę harcerza, wiele problemów zostanie rozwiązanych.

Styl kodu

Styl kodu jest nie mniej ważny, dlatego powinieneś określić go w swoim zespole.

Nie obchodzi mnie, czy lubisz pojedyncze cytaty, podwójne cytaty, spacje lub tabulatory, końcowy przecinek lub brak końcowego przecinka. Wybierz 1 styl i trzymaj się go. Możesz to zrobić z linterem i/lub z prettierem.

Jest tak wiele narzędzi do rozwiązania tego rodzaju problemów. Moim ulubionym jest przechwytywanie przed zatwierdzeniem przy użyciu Husky. Prettier ma również stronę w swojej dokumentacji o punktach przechwytywania przed zatwierdzeniem.

Ten punkt zaczepienia przed zatwierdzeniem zawsze uruchamia skonfigurowane polecenie przed każdym zatwierdzeniem. Jeśli skonfigurujesz go we właściwy sposób, będzie działał lepiej i zastosuje wszystkie reguły do ​​wszystkich plików. Daje to pewność, że zespół zawsze ma ten sam styl kodu bez złego kodu.

Podsumowanie

Wiem, że niektóre zasady są oczywiste, a inne nie. Ale jako pełnoetatowy programista pracuję na różnych bazach kodu. Znaczenie tych reguł staje się jasne dopiero w większych bazach. Ale to nie znaczy, że nie powinieneś ich stosować również w mniejszych projektach. Poprawa jakości kodu pomoże Ci być bardziej wydajnym także w mniejszych projektach. Pomoże to również Twojemu zespołowi w czytaniu kodu i zatwierdzaniu twoich pull requests. Jak powiedziałem, czytelny kod jest łatwiejszy w utrzymaniu, ale ma też wiele innych zalet.

Joachim Zeelmaekers -Jestem młodym i pełnym zapału programistą javascript. Jako programista staram się skupić na jakości, stosując najlepsze praktyki i zasady czystego kodu. Najważniejsze dla mnie jest dzielenie się wiedzą, dlatego moim celem jest motywowanie i mentorowanie młodszych programistów oraz pomaganie im w doskonaleniu ich pracy.