Banyak fungsi bawaan JavaScript yang mendukung sejumlah argumen.
Misalnya:
Math.max(arg1, arg2, ..., argN)
– mengembalikan argumen terbesar.
Object.assign(dest, src1, ..., srcN)
– menyalin properti dari src1..N
ke dest
.
…dan sebagainya.
Dalam bab ini kita akan belajar bagaimana melakukan hal yang sama. Dan juga, cara meneruskan array ke fungsi seperti parameter.
...
Suatu fungsi dapat dipanggil dengan sejumlah argumen berapa pun, tidak peduli bagaimana fungsi tersebut didefinisikan.
Seperti di sini:
fungsi jumlah(a, b) { kembalikan a+b; } peringatan( jumlah(1, 2, 3, 4, 5) );
Tidak akan ada kesalahan karena argumen yang “berlebihan”. Namun tentu saja hasilnya hanya dua yang pertama yang dihitung, jadi hasil pada kode di atas adalah 3
.
Parameter lainnya dapat dimasukkan dalam definisi fungsi dengan menggunakan tiga titik ...
diikuti dengan nama array yang akan menampungnya. Titik-titik secara harfiah berarti “kumpulkan parameter yang tersisa ke dalam sebuah array”.
Misalnya, untuk mengumpulkan semua argumen ke dalam array args
:
function sumAll(...args) { // args adalah nama array misalkan jumlah = 0; untuk (biarkan arg dari args) jumlah += arg; jumlah pengembalian; } peringatan(jumlahSemua(1) ); // 1 peringatan(jumlahSemua(1, 2) ); // 3 waspada( jumlahSemua(1, 2, 3) ); // 6
Kita dapat memilih untuk mendapatkan parameter pertama sebagai variabel, dan hanya mengumpulkan sisanya.
Di sini dua argumen pertama masuk ke dalam variabel dan sisanya masuk ke dalam array titles
:
function showName(Nama Depan, Nama Belakang, ...judul) { peringatan(Nama Depan + ' ' + Nama Belakang ); // Julius Kaisar // sisanya masuk ke array judul // yaitu judul = ["Konsul", "Imperator"] peringatan( judul[0] ); // Konsul peringatan( judul[1] ); // Imperator alert( title.length ); // 2 } showName("Julius", "Caesar", "Konsul", "Imperator");
Parameter lainnya harus ada di akhir
Parameter lainnya mengumpulkan semua argumen yang tersisa, sehingga hal berikut ini tidak masuk akal dan menyebabkan kesalahan:
function f(arg1, ...rest, arg2) { // arg2 setelah ...rest ?! // kesalahan }
...rest
harus selalu menjadi yang terakhir.
Ada juga objek seperti array khusus bernama arguments
yang berisi semua argumen berdasarkan indeksnya.
Misalnya:
fungsi tampilkanNama() { alert( argument.length ); peringatan( argumen[0] ); peringatan( argumen[1] ); // dapat diubah // for(biarkan arg argumen) alert(arg); } // menunjukkan: 2, Julius, Caesar showName("Julius", "Kaisar"); // menunjukkan: 1, Ilya, tidak terdefinisi (tidak ada argumen kedua) showName("Ilya");
Di masa lalu, parameter istirahat tidak ada dalam bahasa tersebut, dan menggunakan arguments
adalah satu-satunya cara untuk mendapatkan semua argumen fungsi. Dan masih berfungsi, kita dapat menemukannya di kode lama.
Namun kelemahannya adalah meskipun arguments
seperti array dan dapat diubah, argumennya bukanlah array. Itu tidak mendukung metode array, jadi kita tidak bisa memanggil arguments.map(...)
misalnya.
Selain itu, selalu berisi semua argumen. Kami tidak dapat menangkapnya sebagian, seperti yang kami lakukan pada parameter istirahat.
Jadi ketika kita membutuhkan fitur-fitur ini, maka parameter lainnya lebih diutamakan.
Fungsi panah tidak memiliki "arguments"
Jika kita mengakses objek arguments
dari fungsi panah, objek tersebut diambil dari fungsi “normal” terluar.
Berikut ini contohnya:
fungsi f() { biarkan showArg = () => alert(argumen[0]); tampilkanArg(); } f(1); // 1
Seperti yang kita ingat, fungsi panah tidak memiliki this
sendiri. Sekarang kita tahu mereka juga tidak memiliki objek arguments
khusus.
Kita baru saja melihat cara mendapatkan array dari daftar parameter.
Namun terkadang kita perlu melakukan hal sebaliknya.
Misalnya, ada fungsi bawaan Math.max yang mengembalikan angka terbesar dari daftar:
waspada( Matematika.max(3, 5, 1) ); // 5
Sekarang katakanlah kita memiliki sebuah array [3, 5, 1]
. Bagaimana kita memanggil Math.max
dengan itu?
Melewatinya “sebagaimana adanya” tidak akan berhasil, karena Math.max
mengharapkan daftar argumen numerik, bukan array tunggal:
misalkan arr = [3, 5, 1]; waspada( Matematika.max(arr) ); // Tidak
Dan tentunya kita tidak bisa membuat daftar item secara manual dalam kode Math.max(arr[0], arr[1], arr[2])
, karena kita mungkin tidak yakin ada berapa jumlahnya. Saat skrip kita dijalankan, mungkin ada banyak, atau mungkin tidak ada sama sekali. Dan itu akan menjadi buruk.
Sebarkan sintaksis untuk menyelamatkan! Tampilannya mirip dengan parameter rest, juga menggunakan ...
, namun justru sebaliknya.
Ketika ...arr
digunakan dalam pemanggilan fungsi, ia “memperluas” objek iterable arr
ke dalam daftar argumen.
Untuk Math.max
:
misalkan arr = [3, 5, 1]; waspada( Matematika.max(...arr) ); // 5 (spread mengubah array menjadi daftar argumen)
Kita juga dapat meneruskan beberapa iterable dengan cara ini:
misalkan arr1 = [1, -2, 3, 4]; misalkan arr2 = [8, 3, -8, 1]; peringatan( Matematika.max(...arr1, ...arr2) ); // 8
Kita bahkan dapat menggabungkan sintaks spread dengan nilai normal:
misalkan arr1 = [1, -2, 3, 4]; misalkan arr2 = [8, 3, -8, 1]; peringatan( Matematika.max(1, ...arr1, 2, ...arr2, 25) ); // 25
Selain itu, sintaks penyebaran dapat digunakan untuk menggabungkan array:
misalkan arr = [3, 5, 1]; misalkan arr2 = [8, 9, 15]; biarkan digabung = [0, ...arr, 2, ...arr2]; waspada(digabung); // 0,3,5,1,2,8,9,15 (0, lalu arr, lalu 2, lalu arr2)
Pada contoh di atas kita menggunakan array untuk mendemonstrasikan sintaks penyebaran, namun iterable apa pun bisa digunakan.
Misalnya, di sini kita menggunakan sintaks spread untuk mengubah string menjadi array karakter:
biarkan str = "Halo"; peringatan( [...str] ); // Halo
Sintaks spread secara internal menggunakan iterator untuk mengumpulkan elemen, sama seperti for..of
.
Jadi, untuk sebuah string, for..of
mengembalikan karakter dan ...str
menjadi "H","e","l","l","o"
. Daftar karakter diteruskan ke penginisialisasi array [...str]
.
Untuk tugas khusus ini kita juga bisa menggunakan Array.from
, karena ia mengubah sebuah iterable (seperti string) menjadi sebuah array:
biarkan str = "Halo"; // Array.from mengubah iterable menjadi array waspada( Array.dari(str) ); // Halo
Hasilnya sama dengan [...str]
.
Namun ada perbedaan halus antara Array.from(obj)
dan [...obj]
:
Array.from
beroperasi pada tipe array dan iterable.
Sintaks spread hanya berfungsi dengan iterable.
Jadi, untuk tugas mengubah sesuatu menjadi array, Array.from
cenderung lebih universal.
Ingatkah saat kita membicarakan Object.assign()
di masa lalu?
Hal yang sama dapat dilakukan dengan sintaks spread.
misalkan arr = [1, 2, 3]; biarkan arrCopy = [...arr]; // sebarkan array ke dalam daftar parameter // lalu masukkan hasilnya ke dalam array baru // apakah arraynya mempunyai konten yang sama? peringatan(JSON.stringify(arr) === JSON.stringify(arrCopy)); // BENAR // apakah arraynya sama? peringatan(arr === arrSalinan); // false (referensi tidak sama) // memodifikasi array awal kita tidak mengubah salinannya: arr.push(4); peringatan(arr); // 1, 2, 3, 4 peringatan(arrCopy); // 1, 2, 3
Perhatikan bahwa hal yang sama dapat dilakukan untuk membuat salinan suatu objek:
misalkan obj = { a: 1, b: 2, c: 3 }; misalkan objCopy = { ...obj }; // sebarkan objek ke dalam daftar parameter // lalu kembalikan hasilnya ke objek baru // apakah objeknya mempunyai isi yang sama? peringatan(JSON.stringify(obj) === JSON.stringify(objCopy)); // BENAR // apakah objeknya sama? peringatan(obj === objCopy); // false (referensi tidak sama) // memodifikasi objek awal kita tidak mengubah salinannya: obj.d = 4; peringatan(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4} peringatan(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3}
Cara menyalin objek ini jauh lebih singkat daripada let objCopy = Object.assign({}, obj)
atau untuk array let arrCopy = Object.assign([], arr)
jadi kami lebih suka menggunakannya kapan pun kami bisa.
Ketika kita melihat "..."
dalam kode, itu adalah parameter istirahat atau sintaks penyebaran.
Ada cara mudah untuk membedakannya:
Ketika ...
berada di akhir parameter fungsi, itu adalah "parameter istirahat" dan mengumpulkan sisa daftar argumen ke dalam array.
Ketika ...
muncul dalam pemanggilan fungsi atau sejenisnya, ini disebut “sintaks spread” dan memperluas array ke dalam daftar.
Gunakan pola:
Parameter istirahat digunakan untuk membuat fungsi yang menerima sejumlah argumen.
Sintaks spread digunakan untuk meneruskan array ke fungsi yang biasanya memerlukan daftar banyak argumen.
Bersama-sama mereka membantu berpindah antara daftar dan serangkaian parameter dengan mudah.
Semua argumen pemanggilan fungsi juga tersedia dalam arguments
"gaya lama": objek iterable seperti array.