Javascript Fundamental — Scope : Part 1 [Bahasa Indonesia]

Tri Hargianto
JogjaJS Community
Published in
6 min readMay 15, 2020
Javascript Scope

Javascript Fundamental — Scope adalah series yang akan membahas scope di Javascript sedikit lebih mendalam. Saya membaginya dalam beberapa bagian, dan series ini masih dalam proses pengerjaan. Oleh karena itu, bagian-bagian selanjutnya dari series ini akan saya publish secepat mungkin. Saya menyarankan anda untuk membaca series ini secara berurutan.“

  1. Bagian 1 : Konsep LHS & RHS look-up, proses Engine memproses variable, konsep Scope & Nested Scope.
  2. Bagian 2 : Lexical Scope & Shadowing Variable
  3. Bagian 3 : Function scope, Global Namespace, IIFE, dan Block Scope

Apa itu scope?

Scope dalam bahasa Indonesia berarti “Lingkup”. Ya, scope yang dimaksud disini memang lingkup. Namun saya lebih memilih menyebut scope daripada “lingkup” supaya kita membiasakan diri dengan terminologi yang umum digunakan.

scope dari apa? Ketika kita membuat sebuah identifier atau variabel, variabel yang kita buat akan hidup di dalam scope tertentu dan itu menentukan di mana saja kita mengakses variabel tersebut. Gambar di bawah ini merupakan salah satu contoh scope di Javascript. Variabel a merupakan variabel global sehingga dapat diakses di dalam function add() , namun variabel b hanya dapat di akses di dalam function add() (scope/lingkup variabel b di definisikan)

Contoh Scope

Dilihat dari contoh di atas, scope terlihat sederhana sekali. Namun apa yang akan di bahas di series tulisan ini lebih kepada, melihat lebih dalam lagi bagaimana scope bekerja di Javascript.

“Write code using Javascript is easy to start. But it can be tough once you starting to deep dive in.”

Saat kita membuat variabel dengan perintah var a = 1; banyak sekali proses yang dijalankan di belakang layar mulai dari alokasi memori, parsing character, generate kode supaya dapat dikenali mesin komputer, dll.

Namun katakanlah proses-proses tersebut ditangani oleh 3 aktor. Yaitu Engine, Compiler, dan Scope.

1. Engine : bertanggung jawab untuk memastikan kode dijalankan dari awal sampai akhir dan juga bertugas mengeksekusi kode JavaScript.

2. Compiler : Bagian dari Engine, Compiler membantu Engine untuk menterjemahkan kode supaya dapat dikenali oleh mesin komputer.

3. Scope : mengalokasikan semua lokasi identifier/variabel dan mengatur bagaimana variabel dapat diakses.

Komunikasi Engine, Compiler, & Scope

Ketika kamu melihat program var a = 1;, kamu mungkin akan berpikir itu merupakan satu statement. Berbeda dengan Engine, ia melihat 2 statement terpisah yaitu var a dan a = 1, yang mana dibantu oleh Compiler untuk memprosesnya.

NB : Saya akan mulai menulis Scope (dengan huruf “S” kapital) sebagai “aktor” dan scope (dengan huruf “s” kecil) sebagai “lingkup”. Semoga kamu tidak bingung ✌️

  1. Ketika Compiler melihat var a , ia meminta bantuan Scope untuk mengecek, apakah variabel a sudah ada di scope tersebut, Jika sudah ada maka Compiler tidak akan meminta Scope untuk membuat variabel baru. Sebaliknya, jika tidak ada variabel a di scope tersebut, Compiler akan meminta Scope untuk membuat variabel baru bernama a .
  2. Setelah kode diterjemahkan oleh Compiler, Engine akan mengekeskusi perintah a = 1; . Pertama, ia akan meminta bantuan Scope untuk mengecek, apakah ada variabel bernamaa di scope tersebut. Jika ternyata variabel a ditemukan, maka Engine akan mengisi angka 1 sebagai nilainya, jika tidak ada, Scope akan mencari di tempat lain (Lihat section “Error” di bawah tentang penjelasan bagaimana cara Scope meng-handle ini).

LHS look-up dan RHS look-up

Ketika Scope mencari eksistensi suatu variabel, terdapat dua metode yang ia lakukan, yaitu Left-Hand-Side (LHS) look-up dan Right-Hand-Side (RHS) look-up.

Anyway, Terminologi ini mungkin bagi sebagian orang akan bertele-tele dan bikin ribet. tapi yah, nice to know 😉. Saya akan coba menyederhanakan arti terminologi ini dengan contoh.

Kenapa disebut Left-Hand-Side? Perhatikan kode berikut:

var a = 1;

Left-Hand-Side look-up artinya proses mencari eksistensi variabel a di scope tertentu dengan tujuan untuk dimasukkan nilai ke dalamnya. Jadi, left side disini maksudnya nama variabel a berada di sisi sebelah kiri operator =.

Selanjutnya, kita coba bahas Right-Hand-Side, kenapa disebut demikian? Perhatikan kode berikut :

console.log(a);

Right-Hand-Side look-up artinya proses mencari variabel a di scope tertentu dengan tujuan untuk meng-ekstrak nilai variabel tersebut.

Oke, kita sekarang paham Left-Hand-Side look-up disebut demikian karena nama variabel berada di sebelah kiri operator =. Tapi Right-Hand-Side tuh kanan dari apanya? kan gak ada tanda =???

Nah, Right-Hand-Side look-up maksudnya look-up yang gak Left-Hand-Side 😂 Lahhh??

Iya betul. Karena kebalikan dari assignment yaitu mengambil nilai, maka kebalikan dari Left yaitu Right.

Quick Quiz

Sekarang coba lihat kode berikut, dan kenali ada berapa banyak LHS look-up dan ada berapa banyak RHS look-up:

function foo(a) {
var b = a;
return a + b;
}
var c = foo( 2 );

Jawabannya : 3 LHS look-up dan 4 RHS look-up. Coba kamu analisa sendiri kenapa jawabannya seperti itu. Pembahasannya ada di akhir bagian tulisan ini.

Nested Scope (scope bersarang)

Sebuah scope dapat bersarang di dalam scope yang lain. Perhatikan kode berikut:

function add(a) {
console.log( a + b );
}
var b = 2;foo( 2 ); // output: 2

Kalau diperhatikan, mungkin kamu bingung mana bersarangnya. Sebenarnya ketika kita membuat function, function tersebut bersarang di dalam scope luarnya, dalam kasus di atas ia berada di dalam global scope.

variabel a di dalam function add hanya dapat di akses melalui function itu sendiri. Namun kalo kita perhatikan, variabel b dapat di akses di dalam function add.

Contoh lagi :

function person() {
var name = "Tri";

function getAge()
var age = 17;

console.log(name); // Tri
console.log(age); // 17
}
console.log(greeting); // hallo
console.log(age); // undefined
}
var greeting = "hallo";console.log(name); // undefined

Aturan simple dari proses LHS maupun RHS look-up adalah, Scope akan mencari dari scope terdekat terlebih dahulu. Jika tidak ketemu maka Scope akan mencari ke scope di atasnya.

Analogi Gedung

Untuk memvisualisasikan proses dari scope bersarang, coba pikirkan konsep gedung tinggi bertingkat, kita sebut gedung itu gedung X, dan kamu adalah orang yang melakukan proses RHS look-up dari variabel bernama cafe.

Gedung X memiliki banyak lantai. Katakanlah lantai pertama (atau lantai berapapun) adalah scope yang saat itu sedang dieksekusi atau dimana kamu berada. Lalu, lantai paling atas adalah global scope.

Jika kamu tidak menemukan cafe di lantai pertama, maka cari di lantai kedua, lalu lantai ketiga, lalu lantai keempat, dan seterusnya. Sesampainya kamu di lantai paling atas (global scope), entah kamu menemukan cafe atau tidak, kamu sudah harus berhenti.

Error

Kenapa penting untuk menyebut dan membedakan antara LHS look-up dan RHS look-up?

Karena cara LHS dan RHS menangani error ketika referensi variabel tidak ditemukan berbeda.

Pada proses RHS look-up, ketika ia mencari variabel bernama cafe dan tidak ketemu walaupun sudah sampai di global scope, maka pesan ReferenceError akan dikeluarkan oleh Engine yang menandakan variabel tidak ditemukan, sehinggakamu harus meng-handle ini jika kamu tidak mau program kamu error.

Sedangkan pada proses LHS look-up, ketika variabel bernama cafe tidak ditemukan walaupun sudah sampai di global scope, maka Global Scope akan membuatkan kita variabel bernama cafe namun dengan nilai default undefined .

[REVIEW] Quick Quiz

function foo(a) {
var b = a;
return a + b;
}
var c = foo( 2 );

Dari kode di atas,

  1. Berapa jumlah LHS look-up? (3) c = ... , a = 2 (implisit) , b = ...
  2. Berapa jumlah RHS look-up? (4) foo(2... , ... = a , a + ... ,... + b

There is no new things under the sun. Tulisan ini diadaptasi dan terinpirasi dari buku Kyle Simpson berjudul You Don’t Know JS: Scope & Closures https://www.amazon.com/gp/product/1449335586

✍ Jika ada penulisan yang salah atau pertanyaan silahkan kirim respon/komentar

--

--