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:
- Te same dane przekazane do funkcji zawsze dają taki sam wynik.
- 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...