Fungsi Tingkat Tinggi dalam JavaScript

Jika Anda mempelajari JavaScript, maka Anda harus menemukan konsep "Fungsi Orde Tinggi". Ini mungkin terlihat seperti sesuatu yang sangat rumit, tetapi pada kenyataannya tidak.

JavaScript cocok untuk pemrograman fungsional karena mendukung konsep fungsi tingkat tinggi. Fungsi seperti itu banyak digunakan dalam bahasa, dan jika Anda memprogram dalam JS, maka Anda mungkin sudah bekerja dengan mereka tanpa menyadarinya.



Untuk memahami konsep ini sepenuhnya, Anda harus terlebih dahulu memahami konsep pemrograman fungsional (Pemrograman Fungsional) dan fungsi-fungsi apa yang kelas satu (Fungsi Kelas Satu).

Materi, terjemahan yang kami terbitkan, ditujukan untuk pemula, ditujukan untuk menjelaskan konsep fungsi tingkat tinggi, dan untuk menunjukkan bagaimana menggunakannya dalam JavaScript.

Apa itu pemrograman fungsional?


Jika Anda menggambarkan konsep pemrograman fungsional dengan kata-kata sederhana, ternyata ini adalah pendekatan pemrograman, yang dengannya Anda dapat mentransfer fungsi ke fungsi lain sebagai parameter dan menggunakan fungsi sebagai nilai yang dikembalikan oleh fungsi lain. Terlibat dalam pemrograman fungsional, kami merancang arsitektur aplikasi dan menulis kode menggunakan fungsi.

Di antara bahasa yang mendukung pemrograman fungsional adalah JavaScript, Haskell, Clojure, Scala, dan Erlang.

Fungsi kelas satu


Jika Anda mempelajari JavaScript, Anda mungkin mendengar bahwa dalam suatu fungsi bahasa diperlakukan sebagai objek kelas satu. Ini karena dalam JavaScript, seperti dalam bahasa lain yang mendukung pemrograman fungsional, fungsi adalah objek.

Secara khusus, dalam fungsi JS direpresentasikan sebagai objek tipe khusus - ini adalah objek tipe Function . Pertimbangkan sebuah contoh:

 function greeting() { console.log('Hello World'); } //   greeting();  //  'Hello World' 

Untuk membuktikan bahwa fungsi dalam JavaScript adalah objek, kita dapat melakukan hal berikut, melanjutkan contoh sebelumnya:

 //     ,       greeting.lang = 'English'; //  'English' console.log(greeting.lang); 

Harap dicatat bahwa saat menambahkan properti Anda sendiri ke objek standar dalam JavaScript tidak menyebabkan pesan kesalahan, melakukannya tidak disarankan. Anda tidak harus menambahkan properti Anda sendiri ke fungsi. Jika Anda perlu menyimpan sesuatu di objek, lebih baik membuat objek khusus untuk ini.

Dalam JavaScript dengan fungsi, Anda dapat melakukan hal yang sama yang dapat dilakukan dengan entitas dari tipe lain, seperti Object , String , Number . Fungsi dapat diteruskan sebagai parameter ke fungsi lainnya. Fungsi seperti itu, ditransfer ke orang lain, biasanya bertindak sebagai fungsi panggilan balik (panggilan balik). Fungsi dapat ditugaskan ke variabel, disimpan dalam array, dan sebagainya. Itu sebabnya fungsi dalam JS adalah objek kelas satu.

Menetapkan Fungsi ke Variabel dan Konstanta


Fungsi dapat ditugaskan ke variabel dan konstanta:

 const square = function(x) { return x * x; } //   25 square(5); 

Fungsi yang ditetapkan ke variabel atau konstanta dapat ditugaskan ke variabel atau konstanta lain:

 const foo = square; //  36 foo(6); 

Melewati fungsi sebagai parameter


Fungsi dapat diteruskan sebagai parameter untuk fungsi lain:

 function formalGreeting() { console.log("How are you?"); } function casualGreeting() { console.log("What's up?"); } function greet(type, greetFormal, greetCasual) { if(type === 'formal') {   greetFormal(); } else if(type === 'casual') {   greetCasual(); } } //  'What's up?' greet('casual', formalGreeting, casualGreeting); 

Sekarang kita tahu bagaimana fungsi kelas satu berperilaku, mari kita bicara tentang fungsi tingkat tinggi.

Fungsi Orde Tinggi


Fungsi tingkat tinggi adalah fungsi yang bekerja dengan fungsi lain, baik sebagai parameter atau mengembalikannya. Sederhananya, fungsi tingkat tinggi adalah fungsi yang mengambil fungsi sebagai argumen atau mengembalikan fungsi sebagai nilai output.

Misalnya, fungsi JavaScript Array.prototype.map , Array.prototype.filter dan Array.prototype.reduce adalah fungsi tingkat tinggi.

Fungsi Perintah Tinggi


Pertimbangkan contoh penggunaan fungsi tingkat tinggi yang dibangun di dalam JS dan bandingkan pendekatan ini dengan tindakan serupa tanpa menggunakan fungsi tersebut.

▍ Metode Array.prototype.map


Metode map() membuat array baru, memanggil, untuk memproses setiap elemen dari array input, panggilan balik diteruskan ke argumen. Metode ini mengambil setiap nilai yang dikembalikan oleh callback dan menempatkannya dalam array output.

Fungsi callback yang dilewatkan ke map() membutuhkan tiga argumen: element (elemen), index (indeks) dan array (array). Mari kita lihat beberapa contoh.

Contoh No. 1


Misalkan kita memiliki larik angka, dan kami ingin membuat larik baru yang berisi hasil dari mengalikan angka-angka ini dengan 2. Pertimbangkan cara untuk menyelesaikan masalah ini menggunakan fungsi tingkat tinggi dan tanpa itu.

Memecahkan masalah tanpa menggunakan fungsi tingkat tinggi


 const arr1 = [1, 2, 3]; const arr2 = []; for(let i = 0; i < arr1.length; i++) { arr2.push(arr1[i] * 2); } //  [ 2, 4, 6 ] console.log(arr2); 

Memecahkan masalah menggunakan peta fungsi tingkat tinggi


 const arr1 = [1, 2, 3]; const arr2 = arr1.map(function(item) { return item * 2; }); console.log(arr2); 

Anda bahkan dapat mengurangi volume kode ini jika Anda menggunakan fungsi panah:

 const arr1 = [1, 2, 3]; const arr2 = arr1.map(item => item * 2); console.log(arr2); 

Contoh No. 2


Misalkan kita memiliki sebuah array yang berisi tahun kelahiran beberapa orang, dan kita perlu membuat sebuah array yang akan mencapai usia mereka pada tahun 2018. Pertimbangkan, seperti sebelumnya, solusi untuk masalah ini dalam dua cara.

Memecahkan masalah tanpa menggunakan fungsi tingkat tinggi


 const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = []; for(let i = 0; i < birthYear.length; i++) { let age = 2018 - birthYear[i]; ages.push(age); } //  [ 43, 21, 16, 23, 33 ] console.log(ages); 

Memecahkan masalah menggunakan peta fungsi tingkat tinggi


 const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = birthYear.map(year => 2018 - year); //  [ 43, 21, 16, 23, 33 ] console.log(ages); 

▍ Metode Array.prototype.filter


Metode filter() menciptakan, berdasarkan array, array baru di mana elemen-elemen array asli jatuh, sesuai dengan kondisi yang ditentukan dalam fungsi callback yang diteruskan ke metode ini. Fungsi ini mengambil, seperti dalam kasus metode map() , 3 argumen: element , index dan array .

Pertimbangkan contoh yang dibuat dengan cara yang sama seperti ketika mempertimbangkan metode map() .

Contoh


Misalkan kita memiliki array yang berisi objek yang propertinya menyimpan informasi tentang nama dan usia perwakilan dari sekelompok orang tertentu. Kita perlu membuat sebuah array di mana hanya akan ada informasi tentang perwakilan dewasa dari grup ini (mereka yang usianya telah mencapai 18 tahun).

Memecahkan masalah tanpa menggunakan fungsi tingkat tinggi


 const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = []; for(let i = 0; i < persons.length; i++) { if(persons[i].age >= 18) {   fullAge.push(persons[i]); } } console.log(fullAge); 

Memecahkan masalah menggunakan filter fungsi tingkat tinggi


 const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = persons.filter(person => person.age >= 18); console.log(fullAge); 

▍ Metode Array.prototype.reduce


Metode reduce() memproses setiap elemen dari array menggunakan panggilan balik dan menempatkan hasilnya dalam nilai output tunggal. Metode ini mengambil dua parameter: callback dan nilai awal opsional ( initialValue ).

Callback menerima empat parameter: accumulator (akumulator), currentValue (nilai saat ini), currentIndex (indeks saat ini), sourceArray (sumber array).

Jika parameter initialValue diberikan ke initialValue , maka, di awal metode, accumulator akan sama dengan nilai ini, dan elemen pertama dari array yang diproses akan ditulis ke currentValue .

Jika parameter initialValue tidak disediakan untuk metode ini, maka elemen pertama array akan ditulis ke accumulator , dan yang kedua ke currentValue .

Contoh


Misalkan kita memiliki array angka. Kita perlu menghitung jumlah elemen-elemennya.

Memecahkan masalah tanpa menggunakan fungsi tingkat tinggi


 const arr = [5, 7, 1, 8, 4]; let sum = 0; for(let i = 0; i < arr.length; i++) { sum = sum + arr[i]; } //  25 console.log(sum); 

Mengatasi masalah menggunakan fungsi urutan yang lebih tinggi berkurang


Pertama, pertimbangkan untuk menggunakan metode reduce() tanpa memberikan nilai awal.

 const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }); //  25 console.log(sum); 

Setiap kali panggilan balik dipanggil dengan currentValue diteruskan ke currentValue , yaitu, elemen array berikutnya, parameter accumulator ternyata berisi hasil operasi sebelumnya, yaitu, apa yang dikembalikan dari fungsi pada iterasi sebelumnya. Setelah penyelesaian metode ini, hasil akhir jatuh ke dalam sum konstan.

Sekarang mari kita lihat seperti apa solusi untuk masalah tersebut jika kita memberikan nilai awal ke metode reduce() .

 const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 10); //  35 console.log(sum); 

Seperti yang Anda lihat, menggunakan fungsi tingkat tinggi telah membuat kode kami lebih bersih, lebih ringkas dan lebih mudah dibaca.

Buat fungsi pesanan tingkat tinggi khusus


Sejauh ini, kami telah bekerja dengan fungsi-fungsi tingkat tinggi yang dibangun dalam JS. Sekarang mari kita buat fungsi kita sendiri yang berfungsi dengan fungsi lain.

Bayangkan bahwa JavaScript tidak memiliki metode array map() standar map() . Kita dapat membuat metode semacam itu sendiri, yang akan diekspresikan dalam pengembangan fungsi tingkat tinggi.

Misalkan kita memiliki larik string, dan kami ingin membuat lariknya dengan angka, yang masing-masingnya mewakili panjang string yang disimpan dalam beberapa elemen array asli.

 const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C']; function mapForEach(arr, fn) { const newArray = []; for(let i = 0; i < arr.length; i++) {   newArray.push(     fn(arr[i])   ); } return newArray; } const lenArray = mapForEach(strArray, function(item) { return item.length; }); //  [ 10, 6, 3, 4, 1 ] console.log(lenArray); 

Dalam contoh ini, kami membuat mapForEach fungsi urutan lebih tinggi, yang mengambil larik dan fungsi panggilan balik fn . Fungsi mapForEach array dalam satu loop dan memanggil fn callback pada setiap iterasi dari loop ini.

fn balik fn menerima elemen string saat ini dari array dan mengembalikan panjang elemen ini. Apa yang dikembalikan fungsi fn digunakan dalam perintah newArray.push() dan masuk ke array yang mapForEach() akan kembali. Array ini pada akhirnya akan ditulis ke konstanta lenArray .

Ringkasan


Dalam artikel ini, kami berbicara tentang fungsi-fungsi tingkat tinggi dan mengeksplorasi beberapa fungsi JavaScript bawaan. Selain itu, kami menemukan cara membuat fungsi tingkat tinggi Anda sendiri.

Singkatnya, esensi dari fungsi tingkat tinggi dapat dikatakan sebagai fungsi yang dapat mengambil fungsi lain sebagai argumen dan mengembalikan fungsi lainnya sebagai hasil dari pekerjaan mereka. Bekerja dengan fungsi lain dalam fungsi tingkat tinggi terlihat sama dengan bekerja dengan objek lain.

Pembaca yang budiman! Apakah Anda harus menulis fungsi tingkat tinggi Anda sendiri?

Source: https://habr.com/ru/post/id428570/


All Articles