Ogrodnik, nie pisz w komentarzach, co twój kod robi, tylko ewentualnie dlaczego robi, to co robi.
Załóżmy, że masz funkcję multiply
:
function multiply(x, y) {
return x*y;
}
i taki kod:
var numbers = [1, 2, 3];
var multipliedNumbers = new Array(numbers.length);
for(var i = 0, len = numbers.length; i < len; i++) {
multipliedNumbers[i] = multiply(numbers[i], i);
}
Jego zadaniem jest wzięcie tablicy, pomnożenie każdego elementu tej tablicy przez jego indeks i zwrócenie nowej tablicy zawierającej te pomnożone elementy. Jeżeli trochę znasz javascript, to wiesz, że jest coś takiego jak funkcja map
. Ten sam kod można zapisać tak:
var multipliedNumbers = numbers.map(multiply);
Prawda, że czytelniej? Oczywiście! Taki refactoring, to rozumiem! Z tym, że nie do końca.
Jeżeli nasza zmienna numbers zawiera kilka elementow, to nie ma problemu, ale przy 1 000 000 elementów rozwiązanie pierwsze jest dwa razy szybsze.
Teraz wracając do komentarzy. Jeżeli byś opisał swój kod tak:
var numbers = [1, 2, 3]; // tablica zawierająca liczby
var multipliedNumbers = new Array(numbers.length); // tworzymy tablicę
// iterujemy po każdym elemencie tablicy z liczbami
for(var i = 0, len = numbers.length; i < len; i++) {
// mnożymy liczbę przez jej indeks i wpychamy do tablicy wynikowej
multipliedNumbers[i] = multiply(numbers[i], i);
}
to jakiś junior developer nie wiedząc dlaczego ten kod tak wygląda wpadnie na pomysł refactoringu i okaże się, że twoja aplikacja chodzi dwa razy wolniej, bo Ci zamieni Twój super wydajny kod na ten bardziej czytelny, myśląc że zrobił coś dobrego. Zamiast tego lepiej by było zrobić coś w ten deseń:
var numbers = [1, 2, 3];
// tworzymy tablicę z użyciem new, zamiast [ ]
// bo pozwala nam to wycisnąć maksymalny performance
var multipliedNumbers = new Array(numbers.length); // widzę, że ktoś Tworzy tablicę, nie muszę tego komentować.
// użycie numbers.map jest dwa razy wolniejsze
for(var i = 0, len = numbers.length; i < len; i++) { // widzę, że to pętla i umiem czytać, więc wiem po czym iteruje
multipliedNumbers[i] = multiply(numbers[i], i);
}
Przykład trochę absurdalny, ale wiadomo o co chodzi. Tak samo przy warunkach często widzę komentarze
// sprawdzamy czy isTo i isTamto i isSramto lub środa
if((isTo && isTamto && isSramto) || isSroda ) {
}
Znacznie lepiej by było gdyby developer zostawił informację, dlaczego ta środa jest taka magiczna.
Jeżeli masz ścianę kodu i naszła Cię chęć dodania komentarza w stylu: "wpisuje nowe dane do zmiennej globalnej", to znaczy, że masz skopany design. Znacznie lepiej jest kod wymagający takiego komentarza zastąpić funkcją, albo nawet zmienną.
Zamiast tego:
var userAgent = navigator.userAgent;
// jezeli ktos nie uzywa androida lub jego wersja jest mniejsza niz 4.3
// i nie używa iphona lub jego wersja jest mniejsza niz 8.0 to wychodzimy z funkcji
if ((!userAgent.match(/android.*?(([0-9]*[.])?[0-9]+)/i) || parseFloat(usingAndroid[1]) < 4.3) &&
(!userAgent.match(/iphone.*?(([0-9]*[_])?[0-9]+)/i) || parseFloat(usingIos[1].replace('_', '.')) < 8.0)) {
return;
}
Lepiej zrobić coś takiego (zwróć uwagę, że jest komentarz, ale tym razem odpowiada na pytanie dlaczego, a nie jak i co):
var
REQUIRED_ANDROID_VERSION = 4.3,
REQUIRED_IOS_VERSION = 8.0,
userAgent = navigator.userAgent,
usingAndroid = userAgent.match(/android.*?(([0-9]*[.])?[0-9]+)/i),
androidVersion = usingAndroid && parseFloat(usingAndroid[1]),
usingIos = userAgent.match(/iphone.*?(([0-9]*[_])?[0-9]+)/i),
iosVersion = usingIos && parseFloat(usingIos[1].replace('_', '.'));
if ((!usingAndroid || androidVersion < REQUIRED_ANDROID_VERSION) &&
(!usingIos || iosVersion < REQUIRED_IOS_VERSION)) {
// to oznacza, że nasza firma nie dostarcza aplikacji
// odpowiedniej dla urządzenia użytkownika
return;
}