Cara menggunakan CLOASURE pada JavaScript

Pada artikel sebelumnya kita membahas berbagai fungsi tingkat tinggi dalam JavaScript. Nah pertanyaannya adalah, apakah fungsi tingkat tinggi hanya tersedia di JavaScript? . Higher-order function tersedia built-in di banyak bahasa pemrograman modern yang terutama memiliki paradigma fungsional, bahkan kita bisa membuatnya sendiri di bahasa pemrograman apapun. Jadi apa sebenarnya fungsi tingkat tinggi itu? . Pada artikel ini saya akan membahas konsep apa saja yang biasa digunakan dalam paradigma fungsional. Oke gak usah lama-lama langsung aja kita mulai


Setidaknya ada beberapa konsep umum dalam paradigma fungsional. itu adalah
  1. Transformasi dan Kekekalan
  2. Fungsi Murni
  3. Fungsi Rekursi/Rekursif
  4. Panggilan Balik dan Penutupan
  5. Fungsi tingkat tinggi
  6. Fungsi Kari/Kari

1. Transformasi dan Kekekalan

Sebelum masuk ke 5 poin yang benar-benar spesifik secara fungsional, pertama-tama kita akan membahas apa itu transformasi dan kekekalan, karena ini adalah dasar dan ciri utama dari paradigma fungsional. Mengapa transformasi dan kekekalan bergabung menjadi satu titik?

Data permanen berarti bahwa data tidak akan dapat mengubah nilainya setelah dibuat. Lalu, mengapa membuat setiap data tidak dapat diubah/permanen? . Dalam paradigma OOP, semua data biasanya bisa berubah. Karena paradigma OOP memungkinkan kita melakukan mutasi data melalui setter pada sebuah class. Misalnya, kami biasanya melakukan ini di Jawa

Yah, mungkin kurang lebih seperti itu kalau kita mengetik program di Java yang paradigmanya menggunakan OOP. Di sana kita dapat melihat bahwa kita telah mengubah nilai diskon dari 10% menjadi 50%. "Lanjutkan, kenapa?"

Betul, Kami telah memutasikan properti diskon pada objek produk dan menyebabkan variabel price1 berubah, karena dalam metode getSalePrice() itu merujuk pada properti diskon pada objek produk. Nah, itulah contoh sederhana dari side-effect event, variabel price1 yang kita deklarasikan di awal juga dipengaruhi oleh side effect ketika kita melakukan mutasi diskon pada objek produk.

Setiap objek dari kelas memiliki status dari propertinya, dan memiliki operasi atau perilaku khusus yang dapat dilakukan pada status melalui metode. Program kami berjalan dengan membuat instance objek dan memodifikasi statusnya melalui metode yang disediakan, biasanya disebut setter. Ketika proyek kita cukup besar dan objek yang dibuat cukup banyak, akan sulit untuk memahami status apa yang ada dalam program kita, dan bagaimana perubahannya dari waktu ke waktu, terutama jika kelas objek saling bergantung dengan kelas lain. Hal ini dapat menyebabkan kesalahan dari engineer dan membuat program sulit untuk dipelihara

Dengan begitu, konsep kekekalan data dalam sebuah kode juga bisa dikatakan penting untuk menghindari kejadian efek samping tersebut. Di Java sebenarnya juga ada konsep immutability, misalnya pada tipe data String seperti ini

Kami melihat bahwa nilai string1 tidak berubah karena pemanggilan string1.toUpperCase(). Tipe data String dalam bahasa Java tidak dapat diubah, kami tidak dapat mengubah nilainya setelah melakukan tugas. Namun, kita dapat menugaskan kembali variabel tipe data String dengan nilai lain. Operasi seperti penggabungan dengan +, .toUpperCase(), dan seterusnya untuk mengembalikan nilai baru dan tidak mengubah nilai awal

Di baris terakhir, sepertinya kita mengganti nilai string1, tetapi yang sebenarnya kita lakukan adalah mengubah referensi yang dimiliki oleh string1 menjadi string baru sebagai hasil dari penggabungan. Lebih detail dalam potongan kode berikut

Terlihat bahwa 10%_2 tidak berubah, karena masih mengacu pada objek string yang sama seperti sebelumnya. Tapi itu hanya sebatas konsep kekekalan di Jawa. Pemrograman berorientasi objek dengan Java sangat mendukung pendekatan mutasi data dalam suatu kelas, melalui setternya, sehingga sangat mungkin menghasilkan kejadian efek samping seperti yang kita lakukan tadi.


Dalam paradigma pemrograman fungsional, keadaan dan perilaku adalah hal yang terpisah. Status diwakili oleh struktur data, dan perilaku adalah fungsi yang dapat beroperasi pada data. Dalam paradigma fungsional, program kami adalah urutan transformasi data dari satu bentuk ke bentuk lainnya

Lalu, bagaimana memperkuat konsep transformasi dan kekekalan dalam paradigma fungsional?

2. Fungsi murni

Setelah membahas konsep transformasi dan kekekalan serta peristiwa efek samping, kita dapat dengan mudah memahami apa itu Fungsi Murni. Secara linguistik, Pure Function dapat diartikan sebagai fungsi murni. Lalu, apa artinya? . Jika kita ingin menulis fungsi murni, aturannya adalah. Pertama, kita tidak dapat mengubah variabel di luar lingkup fungsi. Kedua, dalam fungsi kita harus mengembalikan nilai atau argumen baru sebagai hasil operasi, dan terakhir, jika menggunakan input parameter yang sama, fungsi murni harus konsisten dalam mengembalikan nilainya. Agar lebih jelas, mari kita lihat contoh fungsi dari potongan kode berikut

Contoh Fungsi Tidak Murni

Contoh Fungsi Murni

3. Rekursif

Setelah Pure Function, kita akan membahas Recursive. Rekursif sendiri merupakan fungsi yang memanggil dirinya sendiri, baik secara langsung maupun tidak langsung. Rekursi adalah salah satu teknik pemecahan masalah yang berguna. Saat menyelesaikan masalah secara rekursif, kita biasanya memecah masalah besar menjadi banyak masalah yang lebih kecil, dan menyelesaikan masalah yang lebih kecil dengan fungsi rekursif. Lalu apa kelebihan iterasi rekursif seperti for-loop, do-while dll? . Jadi apa itu rekursi ekor? . Bagaimanapun, jika masalah teoretis yang lebih dalam di luar kemampuan saya, saya tidak akan menjelaskan apa yang di luar kemampuan saya. Oke, mari kita lihat contoh perbandingan penggunaan rekursif dengan iterasi, dengan asumsi saya ingin membuat fungsi 10%3 seperti di Python pada JavaScript

Di dalam fungsi 10%_4 ada panggilan ke fungsi 10%5 itu sendiri, itulah yang disebut rekursif. Fungsi rekursif harus memiliki kondisional untuk membatasi panggilannya. Karena jika tidak maka akan menyebabkan ukuran maksimum callstack melebihi dimana fungsi tidak berhenti memanggil dirinya sendiri, event tersebut persis sama dengan infinite looping. Namun disini terdapat perbedaan antara maximum callstack dan infinite looping dimana jika infinite looping biasanya program akan tetap berjalan tetapi menghasilkan bug yang lama kelamaan program akan freeze/hang hingga crash bahkan OS restart sendiri karena memakan memori yang berlebihan. Sedangkan maximum callstack langsung mengirimkan error tanpa menyebabkan freeze/hang atau bug pada program. Mungkin inilah salah satu keuntungan menggunakan fungsi rekursif daripada perulangan

Kemudian jika dilihat dari hasil nya jelas sama, tapi dari segi singkatnya kode nya sudah jelas kalau menggunakan metode rekursif lebih simple, elegan dan terlihat sangat fungsional.

4. Panggilan Balik dan Penutupan

Callback sebenarnya adalah fungsi biasa, bedanya dengan fungsi pada umumnya adalah pada cara eksekusinya. Jika fungsi umumnya dijalankan secara berurutan dari atas ke bawah kemudian callback dijalankan pada titik tertentu, makanya disebut callback

Nah, salah satu fitur khusus dari callback ini adalah fungsinya sebagai parameter. Dalam JavaScript, panggilan balik adalah kebutuhan pokok sehari-hari. Jika kita sering bermain di JavaScript, sangat kecil kemungkinannya jika kita tidak menemui callback. Mari kita lihat contoh callback yang biasa ditemukan di JavaScript

Nah, kita sudah melihat contoh callback, jadi bagaimana dengan penutupan?

Jadi, apa bedanya? . Untuk definisi sederhananya, yaitu. Penutupan adalah panggilan balik yang memiliki konteks variabel yang akan digunakan. Di sini contohnya bisa dilihat dari variabel event pada callback

Walaupun disini saya menyebutkan perbedaan antara callback dan closure, tapi kebanyakan orang juga tidak membedakan keduanya, karena ya perbedaannya sangat minim haha. Jadi, sebenarnya terserah kita untuk memanggil semuanya panggilan balik atau penutupan

Nah, callback dan closure ini umumnya digunakan untuk implementasi event listener, proses asinkron dan sebagainya

5. Fungsi tingkat tinggi

Kita telah membahas tentang Higher-order function di JavaScript pada artikel sebelumnya dalam 2 bagian. Tapi yang kita bahas kemarin hanya dari luarnya saja. Lalu apa yang ada di dalamnya?

Tapi izinkan saya mengulangi maksudnya lagi, Higher-Order function atau fungsi tingkat tinggi dalam bahasa Indonesia adalah fungsi yang menerima fungsi panggilan balik sebagai argumen atau nilai sebagai keluaran. Nah disini kita menggeneralisasikan callback atau closure sebagai callback, jadi tidak ribet haha. Ya meskipun di poin 4 kita sudah membedakan antara callback dan closure, yang penting kita sudah tahu apa bedanya

Misalnya, jika sebelumnya fungsi 10%_6 dan 10%7 di JavaScript hadir secara terpisah, anggap saja kita ingin membuat fungsi peta dan filter sekaligus dalam satu fungsi agar lebih optimal, haha

Dapat dilihat bahwa fungsi 10%_8 yang disebut dalam fungsi 10%9 bertindak sebagai argumen logis, sedangkan 50%0 bertindak sebagai nilai keluaran. Nah, dua fungsi yang menjadi parameter disebut callback, dan fungsi 10%9 itu sendiri disebut fungsi tingkat tinggi. Namun, callback itu sendiri tidak selalu memenuhi persyaratan fungsi tingkat tinggi. Karena kemungkinan callback hanya dipanggil untuk menyelesaikan proses tanpa mengembalikan argumen atau nilai sebagai output. Sedangkan syarat suatu fungsi dikatakan sebagai fungsi tingkat tinggi adalah jika fungsi tersebut menerima parameter callback yang mengembalikan argumen atau nilai sebagai keluaran


Tapi apa yang perlu diketahui. Callback adalah fungsi yang dipanggil di dalam fungsi lain. Sedangkan fungsi tingkat tinggi adalah kebalikannya, yaitu fungsi yang memanggil fungsi lain. Namun, kebanyakan orang masih menyebutnya fungsi tingkat tinggi meskipun callback yang dipanggil dalam fungsi tersebut tidak memenuhi persyaratan fungsi tingkat tinggi (me-return value)

Omong-omong, kode yang dipraktekkan di atas menggunakan rekursi, jika ingin menggunakan iterasi tidak ada salahnya

6. Kari

Yang terakhir adalah Currying atau bisa juga disebut Curried Function. Secara bahasa, kari berarti rempah-rempah/kari. Kalau secara umum kita istilahkan Gulai Fungsi adalah fungsi yang sudah ditaburi bumbu/kari

Namun secara teknis, Currying adalah teknik mengubah suatu fungsi dengan banyak parameter/argumen menjadi perincian banyak fungsi, setiap fungsi harus mengambil setiap parameter yang tersedia. Mari kita lihat contoh cuplikan kode ini

Fungsi tanpa kari

Mungkin itu fungsi yang biasa kita tulis, jadi mari kita hancurkan parameternya dan buat fungsi tersebut menjadi kari

Berfungsi dengan kari

Jika hasilnya sama, lalu apa untungnya melakukan itu?

Oke, mari kita lihat manfaat menggunakan gulai. Asumsikan bahwa kita memiliki diskon yang sama tetapi harga produk berbeda. Jika tanpa teknik kari, mungkin kita akan menulis seperti ini

Sekilas tidak ada yang salah dengan kode di atas, dan memang tidak ada yang salah. Hanya saja banyak pengulangan parameter untuk diskon

Nah, dibandingkan dengan kode di atas, mari kita coba menggunakan fungsi 50%2 yang menggunakan currying tadi

const discount = getSalePrice('50%')

const price1 = discount(10000)
const price2 = discount(750000)
const price3 = discount(40000)

Ya itu benar. Dengan melakukan currying, kita dapat menahan atau menahan suatu parameter yang mungkin digunakan berulang kali, hal ini membuat parameter di fungsi kita dapat digunakan kembali. Kita sering melihat penerapan teknik kari ini. Contohnya umumnya ada pada framework React, seperti. kait reaksi, komponen tingkat tinggi, dll. Selain itu, banyak implementasi currying juga ditemukan di modul konfigurasi


Penutupan

Kami menyimpulkan bahwa konsep dan teknik dalam paradigma fungsional tidak kalah menariknya dengan konsep dan teknik dalam paradigma OOP seperti yang kita ketahui pada umumnya. Berbeda dengan paradigma OOP yang merupakan sekelompok objek yang dapat berkomunikasi dan bergantung satu sama lain, pendekatan paradigma fungsional adalah sekelompok fungsi kecil yang beroperasi pada data secara mandiri.

Jadi, dibandingkan dengan berpikir bahwa program kita adalah sekelompok objek yang datanya dapat berkomunikasi dan bergantung satu sama lain, lebih baik berpikir bahwa program kita adalah sekelompok fungsi kecil yang beroperasi dengan datanya masing-masing secara mandiri. Apalagi sekarang Microservice sedang trending. Contoh sederhana seperti. Fungsi AWS lambda, fungsi Google Cloud, fungsi Firebase, dan sebagainya. Dari segi flow, sebenarnya arsitektur microservice sama persis dengan flow paradigma fungsional. Karena dalam microservices, layanan yang dibangun bersifat independen dan tidak bergantung pada layanan lain

Dan sebenarnya kita tidak harus selalu memilih dan hanya menggunakan salah satu dari dua paradigma tersebut. Kami dapat dengan sangat baik jika kami ingin menggabungkan paradigma OOP dengan paradigma fungsional dalam proyek kami dengan mencatat bahwa bahasa pemrograman yang kami gunakan mendukung banyak paradigma. Karena ada beberapa bahasa pemrograman yang tidak mendukung multiple paradigma dan dibuat khusus untuk menggunakan satu paradigma tertentu saja


Nah, mungkin itu saja konsep paradigma fungsional yang dapat saya bahas pada artikel kali ini. Jika ada kesalahan dalam penjelasan dan praktek yang saya lakukan di atas, bisa diinterupsi. Memang, saya masih harus banyak belajar. Sekian dari gua, semoga bermanfaat, dan terima kasih. 😄

Apa itu penutupan dalam javascript?

Cukup Penutupan dalam Javascript adalah fungsi di dalam fungsi. Jadi, di dalam fungsi (disebut outer) ada fungsi (disebut inner). Tapi lebih tepatnya closure adalah inner function yang memiliki akses ke variabel yang dimiliki oleh outer function.

Apa yang dimaksud dengan fungsi dalam Javascript?

Fungsi adalah blok (kelompok) perintah pengkodean (pernyataan) yang memiliki tujuan atau fungsi tertentu. Fungsi diproses atau dieksekusi saat dipanggil oleh pengkodean lain