JavaScript

Belum masuk. Progresmu tidak tersimpan.

Masuk
  • Bab 8 dari 12
  • 30 menit
  • 1 latihan kode
  • 4 soal kuis

ES6: let, const, Arrow Function, dan Template Literals

Di bab ini (9 bagian)
  1. Tujuan
  2. Apa itu ES6?
  3. Kenapa ES6 penting buat kamu?
  4. let, const, dan var
  5. Hoisting dan Temporal Dead Zone
  6. Arrow function
  7. Template literals
  8. Kesalahan umum
  9. Rangkuman

Tujuan bab ini

  • Memahami apa itu ES6 (ES2015) dan kenapa hampir semua kode JavaScript modern memakainya.
  • Membedakan var, let, dan const dari sisi scope, redeclare, reassign, dan hoisting.
  • Menulis arrow function dan memahami implicit return serta this leksikal.
  • Membuat string dengan template literals dan mengenal tagged template.

Apa itu ES6?

JavaScript punya "buku aturan" resmi bernama ECMAScript, dikelola komite TC39 di bawah Ecma International. Browser dan Node.js membaca buku aturan ini untuk tahu sintaks apa saja yang harus didukung.

Versi ke-6 dirilis Juni 2015, sehingga punya dua nama: ES6 dan ES2015. Ini pembaruan terbesar sepanjang sejarah JavaScript. Sebelumnya, versi besar terakhir adalah ES5 (2009). Sesudah 2015, TC39 merilis versi baru setiap tahun (ES2016, ES2017, dan seterusnya) dengan fitur yang lebih kecil-kecil.

TahunVersiYang penting
2009ES5strict mode, JSON, method array seperti forEach dan map
2015ES6 / ES2015let/const, arrow function, class, module, Promise, destructuring
2016+ES2016 dan seterusnyaRilis tahunan, misalnya async/await di ES2017

Evolusi ECMAScript dari ES5 ke ES2015 dan rilis tahunan

Kenapa ES6 penting buat kamu?

  • Framework modern memakainya. Tutorial React, Vue, dan Angular penuh dengan arrow function, destructuring, dan import. Tanpa paham ES6, kode mereka terasa seperti bahasa asing.
  • Didukung di mana-mana. Semua browser modern dan Node.js sudah mendukung ES6 secara native.
  • Kode lebih rapi dan aman. let/const mencegah bug scope klasik, module membuat kode terbagi per file, Promise merapikan kode asynchronous.

Anggap ES6 sebagai "bahasa sehari-hari" JavaScript sekarang. Kode gaya ES5 tetap jalan, tapi kamu akan jarang menulisnya.

let, const, dan var

Sebelum ES6, satu-satunya cara membuat variabel adalah var. Masalahnya, var punya perilaku yang sering bikin kaget. ES6 menambahkan let dan const dengan aturan lebih ketat.

Aspekvarletconst
ScopeFunctionBlockBlock
Boleh dideklarasi ulangYaTidakTidak
Boleh diisi ulangYaYaTidak
Akses sebelum deklarasiundefinedReferenceError (TDZ)ReferenceError (TDZ)
Wajib diberi nilai awalTidakTidakYa

Block scope

Block adalah apa pun yang diapit { }: isi if, for, atau sekadar kurung kurawal. Variabel let dan const hanya hidup di dalam block tempat ia dibuat. var mengabaikan block dan "bocor" ke seluruh fungsi.

if (true) {
  var a = "var bocor";
  let b = "let terkunci";
}
console.log(a); // var bocor
console.log(b); // ReferenceError: b is not defined

Contoh bug klasik dengan var di dalam loop:

const fnVar = [];
for (var i = 0; i < 3; i++) {
  fnVar.push(() => i);
}
console.log(fnVar.map((f) => f())); // [ 3, 3, 3 ]

const fnLet = [];
for (let j = 0; j < 3; j++) {
  fnLet.push(() => j);
}
console.log(fnLet.map((f) => f())); // [ 0, 1, 2 ]

Dengan var, hanya ada satu i untuk seluruh loop, dan saat fungsi dipanggil nilainya sudah 3. Dengan let, setiap putaran mendapat j baru.

const bukan berarti isinya beku

const melarang variabelnya diisi ulang, tapi isi objek atau array tetap bisa diubah.

const keranjang = ["kopi"];
keranjang.push("roti");     // boleh
console.log(keranjang);     // [ 'kopi', 'roti' ]
keranjang = [];             // TypeError: Assignment to constant variable.

Aturan praktis: pakai const sebagai default, ganti ke let hanya kalau nilainya memang perlu diganti, dan hindari var.

Hoisting dan Temporal Dead Zone

Hoisting artinya JavaScript sudah "mencatat" semua deklarasi variabel di sebuah scope sebelum menjalankan baris pertamanya. Ibarat guru yang sudah pegang daftar absen sebelum murid masuk kelas.

Bedanya ada di apa yang terjadi kalau variabel dipakai sebelum barisnya:

console.log(a); // undefined
var a = 10;
console.log(a); // 10

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
  • var dicatat dan langsung diberi nilai undefined. Tidak error, tapi diam-diam salah.
  • let dan const juga dicatat, tapi belum boleh disentuh sampai baris deklarasinya dijalankan. Rentang dari awal block sampai baris deklarasi itu disebut Temporal Dead Zone (TDZ).

TDZ sebenarnya membantu: error yang jelas jauh lebih baik daripada undefined yang menyusup ke perhitunganmu.

Arrow function

Arrow function adalah cara singkat menulis fungsi.

// ES5
var tambah = function (a, b) {
  return a + b;
};

// ES6
const tambah2 = (a, b) => a + b;
const kuadrat = (x) => x * x;      // satu parameter, kurung boleh dihapus: x => x * x
const halo = () => "Halo!";        // tanpa parameter, kurung wajib

console.log(tambah2(2, 3)); // 5
console.log(kuadrat(4));    // 16

Implicit return

Kalau badan fungsi hanya satu ekspresi tanpa kurung kurawal, hasilnya otomatis di-return. Begitu kamu memakai { }, kamu wajib menulis return sendiri.

const a = (x) => x * 2;          // return otomatis
const b = (x) => { x * 2; };     // TIDAK return apa-apa
console.log(a(5), b(5));         // 10 undefined

// Mengembalikan objek: bungkus dengan ( )
const buatUser = (nama) => ({ nama, aktif: true });
console.log(buatUser("Sari"));   // { nama: 'Sari', aktif: true }

this leksikal

Fungsi biasa menentukan this dari cara ia dipanggil. Arrow function tidak punya this sendiri; ia memakai this dari tempat ia ditulis. Ini sangat berguna untuk callback di dalam method.

const timer = {
  detik: 0,
  mulai() {
    [1, 2, 3].forEach(() => {
      this.detik++; // this = timer, karena arrow mewarisi dari mulai()
    });
    return this.detik;
  },
};
console.log(timer.mulai()); // 3

Kalau callback di atas ditulis dengan function () { ... }, this di dalamnya bukan timer lagi dan kodenya gagal. Sebaliknya, karena tidak punya this sendiri, arrow function jangan dipakai sebagai method objek yang butuh this. Arrow function juga tidak bisa dipanggil dengan new dan tidak punya objek arguments.

Template literals

Template literal memakai backtick (`), bukan kutip.

const nama = "Mujahidin";
const kelas = "Kelas A";

const lama = "Halo " + nama + ", selamat datang di " + kelas + "!";
const baru = `Halo ${nama}, selamat datang di ${kelas}!`;
console.log(baru); // Halo Mujahidin, selamat datang di Kelas A!

// Di dalam ${} boleh ekspresi apa saja
const harga = 15000;
console.log(`Total: ${harga * 2}, ${harga > 20000 ? "mahal" : "murah"}`);
// Total: 30000, murah

// Multi-line tanpa \n
const puisi = `Baris satu
Baris dua`;
console.log(puisi);
// Baris satu
// Baris dua

Tagged template singkat

Kalau sebuah fungsi ditulis tepat di depan template literal, fungsi itu menerima potongan teks dan nilai sisipan secara terpisah, lalu bebas mengolahnya.

function tebal(strings, ...values) {
  return strings.reduce((hasil, str, i) => {
    const nilai = i < values.length ? `**${values[i]}**` : "";
    return hasil + str + nilai;
  }, "");
}

const mhs = "Dini";
const skor = 95;
console.log(tebal`Mahasiswa ${mhs} mendapat nilai ${skor}.`);
// Mahasiswa **Dini** mendapat nilai **95**.

Di sini strings berisi ["Mahasiswa ", " mendapat nilai ", "."] dan values berisi ["Dini", 95]. Library seperti styled-components dan graphql-tag memakai teknik ini.

Kesalahan umum

  • Memakai var di loop yang membuat callback, lalu heran semua hasilnya sama.
  • Mengira const membuat objek tidak bisa diubah. Yang dikunci hanya variabelnya.
  • Lupa return saat arrow function memakai { }.
  • Mengembalikan objek tanpa kurung: () => { nama: "A" } dianggap block, hasilnya undefined.
  • Memakai arrow function sebagai method yang butuh this.
  • Menulis ${} di dalam kutip biasa. "Halo ${nama}" tetap tercetak apa adanya; harus pakai backtick.

Rangkuman

  • ES6 (ES2015) adalah pembaruan terbesar JavaScript dan fondasi framework modern; sejak itu ECMAScript rilis tiap tahun.
  • let dan const bersifat block scope dan punya TDZ; var function scope dan di-hoist sebagai undefined.
  • Default pakai const, let kalau perlu diisi ulang, hindari var.
  • Arrow function lebih ringkas, punya implicit return, dan mewarisi this dari tempat ia ditulis.
  • Template literal memakai backtick, mendukung ${ekspresi} dan multi-line; tagged template mengolah potongan teks dan nilainya lewat fungsi.

Selesaikan bab ini

  1. 1. Baca materi
  2. 2. Latihan kode (1)
  3. 3. Kuis (4 soal)

Latihan kode: Rapikan kode lama dengan gaya ES6

Lengkapi tiga fungsi berikut memakai fitur ES6:

  • formatPesanan(nama, harga, qty) mengembalikan teks dengan template literal, format "<nama> x<qty> = Rp<harga * qty>". Contoh: formatPesanan("Kopi", 15000, 2) menghasilkan "Kopi x2 = Rp30000".
  • kuadratSemua(angka) mengembalikan array baru berisi kuadrat setiap angka, pakai map dengan arrow function. Contoh: kuadratSemua([1, 2, 3]) menghasilkan [1, 4, 9].
  • buatPenghitung() mengembalikan array berisi 3 fungsi. Fungsi ke-0 mengembalikan 0, ke-1 mengembalikan 1, ke-2 mengembalikan 2. Kode awalnya memakai var dan semua fungsi mengembalikan 3. Perbaiki.

Cek pemahaman

  1. 1ECMAScript 6 juga dikenal dengan nama apa?

  2. 2Apa yang ditampilkan kode berikut?

    const fns = [];
    for (var i = 0; i < 3; i++) {
      fns.push(() => i);
    }
    console.log(fns.map((f) => f()).join(","));
  3. 3Apa yang ditampilkan kode berikut?

    const a = (x) => { x * 2; };
    const b = (x) => x * 2;
    console.log(a(4), b(4));
  4. 4Array yang disimpan di variabel const tetap bisa ditambah isinya dengan push.