JavaScript: Czym jest czysta funkcja?

Opublikowano: 16.08.2022 - tagi: JavaScript Funkcja

Czym to jest czysta funkcja?

Czysta funkcja (ang.: pure function) jest to termin z programowania funkcjonalnego, który mówi, że funkcja jest "czysta" jeśli są spełnione następujące warunki:

  1. Te same dane przekazane do funkcji zawsze dają taki sam wynik.
  2. Funkcja nie tworzy efektów ubocznych.

Przyjrzyjmy się obu warunkom bliżej.

Dane na wejściu, wynik na wyjściu

Te same dane przekazane do funkcji zawsze dają taki sam wynik.

Czyli: dla taki samych parametrów funkcja zawsze powinna zwrócić ten sam wynik:

const multiply = (num, by) => num * by;

console.log(multiply(2, 3)); // 6
console.log(multiply(2, 4)); // 8
console.log(multiply(2, 3)); // 6

Podajemy dwa razy te same parametry: 2 i 3 i dostajemy ten sam wynik: 6. To jest czysta funkcja.

Inny przykład:

console.log(Math.random()); // 0.2755161550452777
console.log(Math.random()); // 0.5888948222087572
console.log(Math.random()); // 0.2976254575123847

To nie jest czysta funkcja! Dla tych samych danych wejściowych dostajemy różne wyniki. Pierwszy warunek nie został spełniony w tym przypadku.

Efekty uboczne

Funkcja nie tworzy efektów ubocznych.

To znaczy, że czysta funkcja nie zmienia stanu danych do niej przekazanych.

Przykład 1

const setProperty = (property, value, object) => {
  object[property] = value;
}

const obj = { name: 'Object' };
setProperty('size', 100, obj); // { name: 'Object', size: 100 }

console.log(obj);

Funkcja setProperty nie można nazwać czystą, ponieważ tworzy efekt uboczny. Zmienia stan obiektu, który jest przekazany do funkcji.

Poprawiona wersja:

const setProperty = (property, value, object) => {
	return ({
		...object,
		[property]: value
	});
}

const obj = { name: 'Object' };
const updatedObject = setProperty('size', 100, obj);

console.log(obj); // { name: 'Object' }
console.log(updatedObject); // { name: 'Object', size: 100 }

Przykład 2

Czysta funkcja nie polega na stanie z zewnątrz:

const counterValue = 10;
const updateCounter = (value) => value + counterValue;

console.log(updateCounter(5)); // 15
console.log(updateCounter(10)); // 20
console.log(updateCounter(10)); // 20

Tutaj niby wszystko jest ok. Daje takie same wyniki na przykład dla parametru 10. Problem jest taki, że działamy na zmiennej z zewnątrz.

A co jeśli zmienimy nieco kod:

let counterValue = 10;
const updateCounter = (value) => value + counterValue;

console.log(updateCounter(5)); // 15
console.log(updateCounter(10)); // 20
counterValue += 15;
console.log(updateCounter(10)); // 35

Ups... mamy już inne wyniki...


JavaScript: Jak zapobiec zmianie wartości tablicy?

Opublikowano: 11.08.2022 - tagi: JavaScript Tablica Kopia

Kopiowanie tablicy

Załóżmy, że mam taki przykład:

const original = [1, 2, 3, 4, 5];
const copy = original;

copy[0] = 7;

console.log('original: ', original); // [7, 2, 3, 4, 5]
console.log('copy: ', copy); // [7, 2, 3, 4, 5]

Stworzyliśmy kopię tablicy, a następnie zmieniliśmy jej pierwszy element. Niestety zmienił się także oryginał. Jest tak dlatego, że w ten sposób skopiowaliśmy także referencje z macierzystej tablicy.

Jak temu zapobiec?

Operator spread: ...

const original = [1, 2, 3, 4, 5];
const copyArray = [...original];

copyArray[0] = 7;

console.log('original: ', original); // [1, 2, 3, 4, 5]
console.log('copyArray: ', copyArray); // [7, 2, 3, 4, 5]

Funkcja slice

const original = [1, 2, 3, 4, 5];
const copyArray = original.slice();

copyArray[0] = 7;

console.log('original: ', original); // [1, 2, 3, 4, 5]
console.log('copyArray: ', copyArray); // [7, 2, 3, 4, 5]

Funkcja concat

const original = [1, 2, 3, 4, 5];
const copyArray = [].concat(original);

copyArray[0] = 7;

console.log('original: ', original); // [1, 2, 3, 4, 5]
console.log('copyArray: ', copyArray); // [7, 2, 3, 4, 5]

Jak zapobiec zmianie w tablicy?

Jeśli zależy nam na stworzeniu tablicy, której zawartości nie chcemy zmieniać w ogóle, możemy użyć: Object.freeze. Pisałem już o niej w tym wpisie.

Przykład:

const array = Object.freeze([1, 2, 3]);

array[0] = 7; // Błąd!
array.push(12); // Błąd!
array.pop(); // Błąd!

Jak widać każda próba modyfikacji tablicy, powoduje błąd w kodzie.


Comics: Big problem, small steps

Opublikowano: 09.08.2022 - tagi: Komiks Rysowanie Problem Produktywność


Ubuntu: Jak sparować słuchawki Airpods Pro?

Opublikowano: 06.08.2022 - tagi: Ubuntu Linux Słuchawki Dźwięk Komenda

Jeśli masz problem z próbą nawiązania połączenia między słuchawkami a Bluetooth Twojego komputera, to wykonaj te kroki:

  1. Edytuj następujący plik:
sudo nano /etc/bluetooth/main.conf

Znajdź: ControllerMode. Jeśli nie ma, to dodaj taki wpis:

ControllerMode = bredr
  1. Zrestartuj Bluetooth:
sudo /etc/init.d/bluetooth restart
  1. Teraz przejdź do ustawień systemów. Dokładnie do sekcji: Bluetooth. Znajdź na liście swoje słuchawki i nawiąż połączenie.

Webstorm: Jak zlokalizować nieużywany kod w projekcie?

Opublikowano: 04.08.2022 - tagi: Webstorm Narzędzie Porada Kod Szukanie

Martwy kod zaśmieca projekt. Skoro go nie używamy to warto go skasować prawda?

Problem pojawia się kiedy pracujemy w dużym projekcie i trzeba sprawdzić wiele plików. Na szczęście Webstorm udostępnia funkcjonalność, która wskazuje miejsca, gdzie znajduje się nieużywany kod.

Jak zlokalizować martwy kod?

Więc po krok po kroku:

  1. Przejdź do: ustawień (skrót: CTRL + ALT + S): File -> Settings -> Inspections.
  2. Znajdź: JavaScript and TypeScript. W drzewku znajdź: Unused symbols.

Domyślnie powinny być zaznaczone wszystkie opcje dla tej kategorii. Jeśli tak nie jest, zaznacz wszystko.

Własny profil inspekcji kodu

Ponieważ jak zauważysz, zaznaczonych jest wiele opcji a Tobie, zależy tylko na znalezieniu martwego kodu, możesz stworzyć specjalny profil dla tej operacji. Zlokalizuj na górze: Profile. Obok znajduje się lista z profilami. Żeby dodać własny, kliknij ikonkę z prawej strony listy. Wybierz opcję Duplicate.... Stworzy nowy profil. Ustaw w nim nazwę na przykład: Dead code. Jest wiele opcji do odznaczenia, ale głowa do góry! Jest szybki sposób na odznaczenie wszystkich opcji. Poniżej listy z profilami jest ikonka: minus w kwadracie kiedy na nią najedziesz kursorem, wyświetli się tooltip z tekstem: Reset to Empty. Kliknij to. Wszystkie opcje są niezaznaczone. Teraz znajdź znowu: Unused symbols. Zaznacz to. Wszystkie opcje dla tej kategorii także zostaną wybrane. Zapisz swoje ustawienia.

Dobra mamy wszystko czas odpalić inspekcję kodu.

Uruchomienie inspekcji kodu

Zamknij okno z ustawieniami. Przejdź do: Code -> Inspect Code....

Wyświetli się okienko. Możesz ustawić sobie lokalizację, w jakim miejscu inspekcja kodu ma się uruchomić. Domyślnie to: Whole project, czyli: cały projekt.

Na koniec wybierz swój profil w Inspection profile.

Kliknij Analyze.

Po chwili wygeneruje się raport z zaznaczonymi miejscami, gdzie znajduje się martwy kod. O ile jakiś istnieje :)