1 September 2021

Parameter rest dan sintaks spread

Banyak fungsi bawaan Javascript yang mendukung argumen dengan angka yang panjang.

Contoh:

  • Math.max(arg1, arg2, ..., argN) – mengembalikan nilai terbesar dari argumen.
  • Object.assign(dest, src1, ..., srcN) – menyalin properti dari src1..N kedalam dest.
  • …dan lainnya.

Didalam bab ini kita akan belajar bagaimana cara untuk melakukan hal yang sama, bagaimana cara untuk mengirim array kepada fungsi seperti itu sebagai parameter.

Parameter rest ...

Sebuah fungsi dapat dipanggil dengan jumlah argumen berapapun, tidak peduli bagaimana itu didefinisikan.

Seperti ini:

function sum(a, b) {
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );

Disana tidak akan terdapat error karena argumen “berlebihan”. Tapi tentu saja hasilnya hanya dua angka pertama yang dihitung.

Sisa parameternya bisa digunakan didalam fungsi dengan menggunakan tiga titik ... diikuti nama dari array yang akan berisi mereka. Titik secara harfiah berarti “kumpulkan sisa parameter didalam array”.

Contoh, untuk mengumpulkan seluruh argumen menjadi array args:

function sumAll(...args) { // args adalah nama dari arraynya
  let sum = 0;

  for (let arg of args) sum += arg;

  return sum;
}

alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6

Kita bisa memilih untuk mendapatkan parameter pertama sebagai variabel, dan sisanya dikumpulkan.

Disini dua parameter pertama akan dimasukan kedalam variabel dan sisanya akan masuk kedalam array titles:

function showName(firstName, lastName, ...titles) {
  alert( firstName + ' ' + lastName ); // Julius Caesar

  // sisanya masuk kedalam array titles
  // i.e. titles = ["Consul", "Imperator"]
  alert( titles[0] ); // Consul
  alert( titles[1] ); // Imperator
  alert( titles.length ); // 2
}

showName("Julius", "Caesar", "Consul", "Imperator");
Parameter rest harus berada di akhir

Parameter rest mengumpulkan seluruh sisa argumen, jadi contoh dibawah tidak dapat dimengerti dan akan menyebabkan error:

function f(arg1, ...rest, arg2) { // arg2 after ...rest ?!
  // error
}

...rest harus selalu berada di akhir.

Variable “arguments”

Juga terdapat objek spesial seperti array bernama arguments yang mengandung seluruh argumen dengan indeksnya.

Contoh:

function showName() {
  alert( arguments.length );
  alert( arguments[0] );
  alert( arguments[1] );

  // dapat diiterasi
  // for(let arg of arguments) alert(arg);
}

// menampilkan: 2, Julius, Caesar
showName("Julius", "Caesar");

// menampilkan: 1, Ilya, undefined (tidak ada argumen kedua)
showName("Ilya");

Dahulu, parameter rest tidak ada didalam bahasa pemrograman, dan menggunakan arguments hanyalah satu-satunya cara untuk mendapatkan seluruh argumen dari sebuah fungsi. Dan itu tetap bekerja, kita bisa menemukannya di kode-kode jadul.

Tapi kekurangannya adalah walaupun arguments seperti array dan bisa diiterasi, itu bukanlah sebuah array. Itu tidak mendukung metode-metode array, jadi kita tidak bisa memanggil untuk contoh arguments.map(...).

Juga, itu selalu mengandung seluruh argumen. Kita tidak bisa menangkapnya dalam beberapa bagian, seperti yang kita lakukan dengan parameter rest.

Jadi ketika kita membutuhkan fiturnya, parameter rest lebih disukai.

Arrow function tidak memiliki "arguments"

Jika kita ingin mengakses objek argumentsdari sebuah fungsi panah/arrow function, itu akan mengambilnya dari fungsi “normal” terluar.

Contoh:

function f() {
  let showArg = () => alert(arguments[0]);
  showArg();
}

f(1); // 1

Seperti yang kita ingat, arrow function tidak memiliki this mereka sendiri. Sekarang kita tahu mereka tidak memiliki objek arguments yang spesial juga.

Sintaks spread

Kita baru saja melihat bagaimana cara untuk mendapatkan sebuah array dari daftar dari sebuah parameter-parameter.

Tapi terkadang kita perlu untuk melakukan hal yang sama dengan terbalik.

Contoh, terdapat fungsi bawaan Math.max yang mengembalikan angka terbesar dari list:

alert( Math.max(3, 5, 1) ); // 5

Sekarang kita bayangkan kita mempunyai sebuah array [3, 5, 1]. Bagaimana caranya kita memanggilMath.max` dengan itu?

Berikan itu “kedalamnya” tidak akan bekerja, karena Math.max mengharapkan sebuah daftar dari argumen numerik, bukan dari array tunggal: