Function - JavaScript
Published: 2024-02-01 14:31:38

Ini adalah sedikit yang saya pelajari dari `function` dalam JavaScript, kalau secara utuh pastinya butuh penjelasan yang panjang. Karena penjelasan parsial dalam bahasa pemrograman apapun pasti mempertimbangkan batasan dimana scope-nya bisa diterapkan.
Sebuah fungsi atau `function` adalah kumpulan `variable` & `method` yang menjalankan satu instruksi khusus. Secara umum penulisan sebuah fungsi adalah sebagai berikut:

```javascript
function namaFungsi(argumentX, argumentY){
 let variable1;
 let variable2;
 function innerFunction(){
  console.log(argumentX, argumentY);
 }
}
```
`argument` adalah parameter yang akan dipakai (atau tidak dipakai) dalam sebuah fungsi. `argument` dapat berupa apa saja, atau dapat ditentukan `default parameter` jika tidak diisi.

```javascript
const tiket = [];
const pesanTiket = function (
  jarak = 5,
  penumpang = 1,
  harga = penumpang * jarak * 3000
) {
  const order = {jarak, penumpang, harga};
  console.log(order);
  tiket.push(order);
};
pesanTiket(); // tidak diisi parameter apapun maka default parameter yang digunakan
pesanTiket(6, 2, 20000);
pesanTiket(10, undefined); // jika diisi undefined atau tidak diisi maka akan dikembalikan nilai default
```

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1qtm6wl1sm7v2gj6vwl6.png)

Passing `argument `dari sebuah object

```javascript
const bus = 'Restu Panda';
const penumpang = {
  nama: 'Harry Potter',
  kursi: '13B',
};
const checkIn = function (armada, pemesan) {
  armada === 'Restu Panda' &&
  pemesan.nama === 'Harry Potter' &&
  pemesan.kursi === '13B'
    ? console.log('OK')
    : console.log('NOT OK');
};
checkIn(bus, penumpang); // output: OK
penumpang.nama = 'Ron Weasley'; // Mengganti key nama dari object penumpang
checkIn(bus, penumpang); // output: NOT OK
```
Pada fungsi diatas kita memasukkan argumen berupa object, maka untuk mengakses `key `dari object tersebut kita memanggil nama object bukan nama argument, yaitu `penumpang.nama` bukan `pemesan.nama`.

Sebuah fungsi bisa menerima argumen berupa fungsi.

```javascript
const single = function (str) {
  return str.replace(/ /g, '').toLowerCase();
};
const capitalize = function (str) {
  const [first, ...other] = str.split(' ');
  return [first.toUpperCase(), ...other].join(' ');
};

const trans = function (str, fn) {
  console.log(`Original string: ${str}`);
  console.log(`Transformed string: ${fn(str)}`);
  console.log(`Transformed by: function ${fn.name}`);
};
trans('javascript is not easy', single);
trans('javascript is not easy', capitalize);
```
![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yz0vj3z3jdegvrx7021q.png)

Sebuah fungsi juga bisa mengembalikan fungsi.

```javascript
const salam = function (ucapan) {
  return function (nama) {
    console.log(`${ucapan} ${nama}`);
  };
};
const hello = salam('Selamat pagi');
hello('Ahmad'); // Output: Selamat pagi Ahmad
hello('Jainal'); // Output: Selamat pagi Jainal
salam('Selamat malam')('Mbah Jum'); // Output: Selamat malam Mbah Jum
```
**IIFE : Immediate Invoke Function Expression**
IIFE adalah sebuah fungsi yang hanya dieksekusi sekali saja pada saat fungsi tersebut dibuat. Ketika kita membuat sebuah variabel, object, array atau fungsi maka JavaScript akan menempatkan kesemuanya dalam window global object. Untuk menghindari pembuatan fungsi yang terlalu banyak maka digunakanlah IIFE. Sesuai dengan namanya IIFE adalah sebuah function expession.

```javascript
// Function expression regular
let tambah = function (a, b) {
  return a + b;
};

// Function expression bisa langsung dieksekusi
let tambah1 = (function (a, b) {
  return a + b;
})(10, 20);
console.log(tambah1); // Output: 30

// Dengan menghilangkan variabel maka terciptalah IIFE
(function (a, b) {
  return console.log(a + b);
})(20, 20); // Output: 40

// Dengan meletakkan fungsi dan variabel kedalam IIFE, kita menghindari penumpukan di global object
(function () {
  function add(a, b) {
    return a + b;
  }
  console.log(add(30, 20));
})(); // Output: 50
```
**Closure**
Closure adalah kombinasi dari fungsi dan variabel didalam ruang fungsi tersebut. Closure memungkinkan varabel lokal diakses dari luar fungsi. Setiap pembuatan fungsi pasti menghasilkan closure.

```javascript
function helloGuys() {
  let sayHello = 'Hallo dari Harry';
  function innerHello() {
    console.log(sayHello);
  }
  return innerHello;
}
// Dengan meng-assign fungsi helloGuys kedalam sebuah variabel maka variabel dan fungsi didalam helloGuys bisa diakses dari luar fungsi tersebut

const halo = helloGuys();
halo(); // Output: Hallo dari Harry

// Yang bisa diakses dari luar fungsi adalah return value
function counter() {
  let count = 0;
  return {
    increment: function () {
      count++;
      console.log(count);
    },
    decrement: function () {
      count--;
      console.log(count);
    },
  };
}
const hitung = counter();
hitung.increment(); // Output: 1
hitung.increment(); // Output: 2
hitung.decrement(); // Output: 1

function multiplier(factor) {
  return function (number) {
    return factor*number;
  };
}
const multiple = multiplier(3);
console.log(multiple(5)); // Output: 15
```