Podstawowe pojęcia w programowaniu funkcjonalnym za pomocą JavaScript
Programowanie funkcyjne to paradygmat, który zyskał popularność w ostatnich latach ze względu na możliwość pisania bardziej modułowego, wielokrotnego użytku i łatwego w utrzymaniu kodu. JavaScript, będąc wszechstronnym językiem programowania, dobrze nadaje się również do programowania funkcjonalnego. W tym artykule przyjrzymy się podstawowym koncepcjom programowania funkcjonalnego za pomocą JavaScript i wyjaśnimy, w jaki sposób mogą one pomóc w pisaniu lepszego kodu:
- Pełni funkcję obywateli pierwszej klasy
- Funkcje wyższego rzędu
- Czyste funkcje
- Niezmienność
- rekursja
W programowaniu funkcyjnym funkcje są traktowane jako obywatele pierwszej klasy, co oznacza, że można je przypisywać do zmiennych, przekazywać jako argumenty do innych funkcji i zwracać jako wartości. Ta koncepcja jest kluczowa w programowaniu funkcjonalnym, ponieważ pozwala nam pisać bardziej modułowy i wielokrotnego użytku kod.
Oto kilka przykładów tego, jak funkcje są traktowane jako obywatele pierwszej klasy w JavaScript:
- Przypisywanie funkcji do zmiennych:
const add = function(x, y) {
return x + y;
}
2. Przekazywanie funkcji jako argumentów:
Funkcje mogą być również przekazywane jako argumenty do innych funkcji. Pozwala to na bardziej modułowe podejście do programowania, ponieważ pozwala nam ponownie wykorzystać tę samą funkcję z różnymi wejściami i wyjściami. Na przykład:
function greet(name, callback) {
const message = "Hello, " + name + "!";
callback(message);
}
function logMessage(message) {
console.log(message);
}
greet("Sumit", logMessage); // Logs "Hello, Sumit!"
3. Zwracanie funkcji jako wartości:
Funkcje mogą być również zwracane jako wartości z innych funkcji. Pozwala to na bardziej zaawansowane techniki, takie jak zamknięcia i curry. Na przykład:
function add(x) {
return function(y) {
return x + y;
};
}
const addFive = add(5);
console.log(addFive(3)); // Logs 8
✓ Funkcje wyższego rzędu
Funkcje wyższego rzędu to funkcje, które przyjmują inne funkcje jako argumenty lub zwracają funkcje jako wartości. Pozwalają nam pisać bardziej abstrakcyjny i uniwersalny kod, który można zastosować w różnych przypadkach użycia. Niektóre popularne funkcje wyższego rzędu w JavaScript to map(), filter() i reduce().
Oto kilka przykładów funkcji wyższego rzędu w JavaScript:
- Tablica.prototyp.map():
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function(num) {
return num * 2;
});
console.log(doubled); // Logs [2, 4, 6, 8]
2. Tablica.prototyp.filtr():
Metoda filter()jest kolejną funkcją wyższego rzędu, która jako argument przyjmuje funkcję wywołania zwrotnego i zwraca nową tablicę zawierającą tylko te elementy, które pomyślnie przeszły test określony w wywołaniu zwrotnym. Na przykład:
const numbers = [1, 2, 3, 4];
const even = numbers.filter(function(num) {
return num % 2 === 0;
});
console.log(even); // Logs [2, 4]
3. Funkcja.prototyp.bind():
Metoda bind()jest funkcją wyższego rzędu, która zwraca nową funkcję z określoną thiswartością i początkowymi argumentami. Jest często używany do tworzenia nowej funkcji z określonym kontekstem lub do tworzenia częściowo zastosowanej funkcji. Na przykład:
const person = {
firstName: "Sumit",
lastName: "Saha",
fullName: function() {
return this.firstName + " " + this.lastName;
}
};
const logName = function(greeting) {
console.log(greeting + " " + this.fullName());
};
const boundLogName = logName.bind(person, "Hello");
boundLogName(); // Logs "Hello Sumit Saha"
To tylko kilka przykładów z wielu funkcji wyższego rzędu dostępnych w JavaScript. Korzystając z funkcji wyższego rzędu, możesz napisać bardziej ogólny i wielokrotnego użytku kod, który można zastosować w różnych przypadkach użycia.
✓ Czyste funkcje
Czyste funkcje to funkcje, które nie mają skutków ubocznych, co oznacza, że nie modyfikują żadnych zewnętrznych stanów ani zmiennych poza swoim zakresem. Zawsze zwracają to samo wyjście dla tego samego wejścia, co czyni je deterministycznymi. Czyste funkcje są niezbędne w programowaniu funkcjonalnym, ponieważ promują przewidywalność kodu, testowalność i łatwość konserwacji.
Oto kilka przykładów czystych funkcji w JavaScript:
- Funkcja dodawania:
function add(a, b) {
return a + b;
}
function concatenateArrays(arr1, arr2) {
return arr1.concat(arr2);
}
3. Funkcja formatowania daty:
function formatDate(date) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}-${month}-${day}`;
}
4. Funkcja wielkich liter ciągu:
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
Ogólnie rzecz biorąc, funkcje czyste to funkcje, które nie mają żadnych skutków ubocznych i zawsze zwracają ten sam wynik dla tego samego wejścia. Są przewidywalne i łatwiejsze do uzasadnienia, co czyni je idealnymi do pisania łatwego w utrzymaniu i wielokrotnego użytku kodu.
✓ Niezmienność
Niezmienność to koncepcja polegająca na unikaniu modyfikowania struktur danych lub zmiennych po ich utworzeniu. Zamiast zmieniać obiekt lub tablicę, tworzymy nowy z pożądanymi zmianami. Takie podejście zapobiega niezamierzonym skutkom ubocznym i sprawia, że kod jest bardziej przewidywalny i łatwiejszy do uzasadnienia.
Oto kilka przykładów niezmienności w JavaScript:
- Używanie operatora spread do tworzenia nowej tablicy lub obiektu:
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4];
// arr1 is still [1, 2, 3], arr2 is [1, 2, 3, 4]
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
// obj1 is still { a: 1, b: 2 }, obj2 is { a: 1, b: 2, c: 3 }
const arr1 = [1, 2, 3];
const arr2 = arr1.concat(4);
// arr1 is still [1, 2, 3], arr2 is [1, 2, 3, 4]
3. Używając Object.assign()do tworzenia nowego obiektu:
const obj1 = { a: 1, b: 2 };
const obj2 = Object.assign({}, obj1, { c: 3 });
// obj1 is still { a: 1, b: 2 }, obj2 is { a: 1, b: 2, c: 3 }
4. Używanie Object.freeze()w celu uniemożliwienia modyfikacji obiektu:
const obj1 = Object.freeze({ a: 1, b: 2 });
obj1.c = 3;
// obj1 is still { a: 1, b: 2 }, the assignment is ignored
Ogólnie rzecz biorąc, niezmienność oznacza, że dane nie są zmieniane bezpośrednio, ale raczej tworzone są nowe kopie po wprowadzeniu zmian. Może to pomóc w zapobieganiu niezamierzonym skutkom ubocznym i sprawić, że kod będzie bardziej przewidywalny i łatwiejszy w utrzymaniu.
✓ Rekurencja
Rekurencja to technika, w której funkcja wywołuje samą siebie w celu rozwiązania problemu. Jest potężnym narzędziem w programowaniu funkcjonalnym, ponieważ pozwala rozwiązywać złożone problemy, dzieląc je na mniejsze, prostsze. Jednak rekurencja może być trudna w użyciu, ponieważ może prowadzić do błędów przepełnienia stosu i problemów z wydajnością, jeśli nie jest używana prawidłowo.
Oto kilka przykładów rekurencji w JavaScript:
- Funkcja czynnikowa:
function factorial(n) {
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
factorial(5); // returns 120 (5! = 5 * 4 * 3 * 2 * 1)
function sum(arr) {
if (arr.length === 0) {
return 0;
} else {
return arr[0] + sum(arr.slice(1));
}
}
sum([1, 2, 3, 4, 5]); // returns 15 (1 + 2 + 3 + 4 + 5)
3. Funkcja Fibonacciego:
function fibonacci(n) {
if (n === 0 || n === 1) {
return n;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
fibonacci(6); // returns 8 (0, 1, 1, 2, 3, 5, 8)
Rekurencja może być potężnym narzędziem w rozwiązywaniu problemów obejmujących powtarzające się wzorce lub struktury. Jednak może to również prowadzić do problemów z wydajnością i błędów przepełnienia stosu, jeśli nie zostanie starannie zaimplementowane. Ważne jest, aby zrozumieć koncepcję rekurencji i rozsądnie używać jej w swoim kodzie.
Wniosek
Podsumowując, programowanie funkcyjne jest ważnym paradygmatem, który może pomóc w pisaniu bardziej modułowego, wielokrotnego użytku i łatwego w utrzymaniu kodu. Dzięki zrozumieniu podstawowych pojęć, takich jak funkcje jako obywatele pierwszej klasy, funkcje wyższego rzędu, funkcje czyste, niezmienność i rekurencja, możesz zacząć pisać bardziej funkcjonalny kod w JavaScript. Programowanie funkcyjne to nie jedyny sposób na napisanie dobrego kodu, ale jest to potężne narzędzie, które może pomóc w rozwiązywaniu złożonych problemów i uczynieniu kodu bardziej przewidywalnym i łatwiejszym do uzasadnienia.

![Czym w ogóle jest lista połączona? [Część 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































