Nasza strona używa cookies. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Dobre praktyki w pisaniu czytelnego kodu w JavaScript

Sprawdź, co należy zrobić, aby pisać bardziej czytelny i łatwiejszy w utrzymaniu kod w JavaScript.
Dobre praktyki w pisaniu czytelnego kodu w JavaScript

Dobry kod jest łatwy do zrozumienia i utrzymania. Można go z łatwością refaktoryzować, ponownie używać i, co najważniejsze, jest czytelny. Osiągnięcie powyższego zawsze było ważne, ale w ostatnich latach stało się jeszcze ważniejsze. Produkty są często wdrażane na wiele sposobów oraz dla różnych odbiorców, urządzeń i platform. Wszystko to sprawia, że współdzielenie i ponowne wykorzystywanie komponentów między projektami jest absolutną koniecznością.

Kod, który nie jest łatwy do wyodrębnienia, ponownego wykorzystania i zrozumienia, nie zostanie przyjęty w innych projektach. Możesz sprawdzić swój własny kod, publikując komponenty w Bit. Jeśli dobrze go zbudujesz, bardzo łatwo będzie Ci je publikować i używać ponownie przy innych projektach.


Zmienne


Zrozumiałe nazwy

Upewnij się, że zmienne mają zrozumiałe nazwy. Zmniejsza to potrzebę dodatkowych komentarzy, ponieważ kod będzie mówił sam za siebie.

//BAD
cosnt ddmmyyyy = new Date();

//GOOD
const date = new Date();



Nazwy łatwe do odnalezienia

Więcej czasu spędzamy na czytaniu niż pisaniu kodu. Dlatego ważne jest, aby był on czytelny i łatwy do przeszukiwania. Jeśli widzisz jakąś wartość i nie masz pojęcia, co ona robi lub ma zrobić, to zdezorientuje to zapewne użytkownika.

//BAD
//Reader would have no clue on what 86400000 is 
setTimeout(randomFunction, 86400000);

//GOOD
// Declare them as capitalized named constants.
const MILLISECONDS_IN_A_DAY = 86_400_000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);



Unikaj map mentalnych

Nie zmuszaj ludzi do zapamiętywania kontekstu zmiennych. Zmienne należy rozumieć nawet wtedy, gdy czytelnikowi nie udało się prześledzić całej historii ich powstania.

// BAD
const names = ["John", "Jane", "Joseph"];
names.forEach(v => {
  doStuff();
  doSomethingExtra();
  // ...
  // ...
  // ...
  // What is this 'v' for?
  dispatch(v);
});

// GOOD
const names = ["John", "Jane", "Joseph"];
names.forEach(name => {
  doStuff();
  doSomethingExtra();
  // ...
  // ...
  // ...
  // 'name' makes sense now
  dispatch(name);
});



Nie dodawaj zbędnego kontekstu

Jeśli nazwa klasy lub obiektu mówi Ci, czym one są, to nie umieszczaj tego w nazwie zmiennej.

// BAD
const Book = {
  bookName: "Programming with JavaScript",
  bookPublisher: "Penguin",
  bookColour: "Yellow"
};

function wrapBook(book) {
  book.bookColour = "Brown";
}
// GOOD
const Book = {
  name: "Programming with JavaScript",
  publisher: "Penguin",
  colour: "Yellow"
};

function wrapBook(book) {
  book.colour = "Brown";
}



Używaj domyślnych argumentów

Warto zadbać o dodanie sensownych domyślnych wartości dla argumentów, co ułatwi wykorzystanie funkcji.

// BAD
function addEmployeeType(type){
const employeeType = type || "intern";
//............
}

// GOOD
function addEmployeeType(type = "intern"){
//............
}



Używaj sprawdzania typu

Zamiast ==, użyj ===. Pomogłoby to uniknąć później wszelkiego rodzaju niepotrzebnych problemów. Jeżeli sprawdzenie przy pomocy == nie zostanie poprawnie obsłużone, może to wtedy dramatycznie wpłynąć na logikę programu.


0 == false // true
0 === false // false
2 == "2" // true
2 === "2" // false



Funkcje


Używaj opisowych nazw, które mówią same za siebie

Biorąc pod uwagę funkcje, które reprezentują określone zachowanie, nazwa takiej funkcji powinna być czasownikiem lub frazą w pełni ujawniającą jej intencję, a także intencję jej argumentów. Innymi słowy, taka nazwa powinna wprost mówić, co taka funkcja robi.

//BAD

function sMail(user){
//........
}

//GOOD

function sendEmail(emailAddress){
//.........
}



Minimalne argumenty funkcji

Najlepiej byłoby unikać długiej liczby argumentów. Ograniczenie liczby parametrów funkcji ułatwi jej testowanie. Jeden lub dwa argumenty to idealny przypadek. Jeśli to możliwe, to należy unikać trzech, a jeszcze większa liczba argumentów powinna zostać skonsolidowana.

Zazwyczaj, jeśli masz więcej niż dwa argumenty, to Twoja funkcja chce zrobić więcej, niż jest wymagane. W innych przypadkach prawdopodobnie wystarczy, że argumentem będzie wysokopoziomowy obiekt. 

//BAD
function createMenu(title, body, buttonText, cancellable) {
  // ...
}

createMenu("Foo", "Bar", "Baz", true);

//GOOD
function createMenu({ title, body, buttonText, cancellable }) {
  // ...
}

createMenu({
  title: "Foo",
  body: "Bar",
  buttonText: "Baz",
  cancellable: true
});



Funkcje powinny robić jedną rzecz

To jedna z najważniejszych zasad w inżynierii oprogramowania. Kiedy Twoja funkcja robi więcej niż jedną rzecz, to trudniej jest testować, komponować i myśleć. Funkcję przypisaną do tylko jednej czynności można łatwo refaktoryzować, a Twój kod będzie wtedy o wiele bardziej czytelny.

Funkcje powinny robić jedną i tylko jedną rzecz i powinny robić ją dobrze.  - Robert C. Martin (znany też jako Uncle Bob)

 

//BAD
function notifyListeners(listeners) {
  listeners.forEach(listener => {
    const listenerRecord = database.lookup(listener);
    if (listenerRecord.isActive()) {
      notify(listener);
    }
  });
}

//GOOD
function notifyActiveListeners(listeners) {
  listeners.filter(isListenerActive).forEach(notify);
}

function isListenerActive(listener) {
  const listenerRecord = database.lookup(listener);
  return listenerRecord.isActive();
}



Usuń duplikaty

Należy dołożyć wszelkich starań, aby uniknąć duplikowania kodu. Pisanie tego samego kodu więcej niż jeden raz to nie tylko strata czasu podczas pisania, ale również podczas utrzymywania go. Zamiast jednej zmiany wpływającej na wszystkie odpowiadające jej moduły, musisz znaleźć wszystkie zduplikowane moduły i powtórzyć tę zmianę.

Często dzieje się tak, że duplikacja kodu ma miejsce, ponieważ dwa lub więcej modułów posiadają niewielkie różnice. Powodują one, że otrzymujemy dwie lub więcej nieco różniących się rzeczy, które mają w rezultacie wiele wspólnego. Małe różnice wymuszają na Tobie posiadanie bardzo podobnych modułów. Usunięcie zduplikowanego kodu oznacza stworzenie abstrakcji, która mogłaby obsłużyć taki zestaw różnych rzeczy za pomocą jednej funkcji, modułu, lub klasy.

//BAD
function showDeveloperList(developers) {
  developers.forEach(developer => {
    const expectedSalary = developer.calculateExpectedSalary();
    const experience = developer.getExperience();
    const githubLink = developer.getGithubLink();
    const data = {
      expectedSalary,
      experience,
      githubLink
    };

    render(data);
  });
}

function showManagerList(managers) {
  managers.forEach(manager => {
    const expectedSalary = manager.calculateExpectedSalary();
    const experience = manager.getExperience();
    const portfolio = manager.getMBAProjects();
    const data = {
      expectedSalary,
      experience,
      portfolio
    };

    render(data);
  });
}

//GOOD
function showEmployeeList(employees) {
  employees.forEach(employee => {
    const expectedSalary = employee.calculateExpectedSalary();
    const experience = employee.getExperience();

    const data = {
      expectedSalary,
      experience
    };

    switch (employee.type) {
      case "manager":
        data.portfolio = employee.getMBAProjects();
        break;
      case "developer":
        data.githubLink = employee.getGithubLink();
        break;
    }

    render(data);
  });
}



Nie zaśmiecaj elementów globalnych

Dodawanie elementów globalnych jest złą praktyką w JavaScript, ponieważ możesz się wtedy zderzyć z inną biblioteką, a użytkownik twojego API nie zorientuje się o tym, dopóki nie otrzyma wyjątku w środowisku produkcyjnym.

Na przykład, jeśli chcesz rozszerzyć natywną metodę Array w JavaScript, aby uzyskać metodę diff, która pokazywałaby różnicę między dwiema tablicami, to możesz napisać swoją metodę do Array.prototype. Może to jednak kolidować z inną biblioteką, która próbowała wywołać tę samą metodę diff, aby zaimplementować inną funkcję.

Dlatego znacznie lepiej byłoby po prostu użyć klas ES2015/ES6 i rozszerzyć globalną tablicę Array.

//BAD
Array.prototype.diff = function diff(comparisonArray) {
  const hash = new Set(comparisonArray);
  return this.filter(elem => !hash.has(elem));
};

//GOOD
class SuperArray extends Array {
  diff(comparisonArray) {
    const hash = new Set(comparisonArray);
    return this.filter(elem => !hash.has(elem));
  }
}


Chociaż czysty kod to obszerny temat, ograniczyłem się tylko do zmiennych i funkcji, aby artykuł nie był za długi. Podałem tylko ułamek tego, co możesz zrobić, aby Twój kod był czytelny i przejrzysty. Gorąco polecam książkę pt. „Czysty kod. Podręcznik dobrego programisty” Roberta C. Martina.


Oryginał tekstu w języku angielskim przeczytasz tutaj.

Rozpocznij dyskusję

Lubisz dzielić się wiedzą i chcesz zostać autorem?

Podziel się wiedzą z 160 tysiącami naszych czytelników

Dowiedz się więcej