JavaScript

Mental Model pada JavaScript

CalendarFeb 2, 2022Clock10 min read

Apa sih mental model dan apa kaitannya dengan bahasa pemrograman?

Begini…

Jika saya dan Elon Musk ditanya tentang bagaimana cara kerja sebuah mesin roket dan jenis bahan bakar apa yang harus digunakan, maka hampir dapat dipastikan bahwa jawaban saya tidak akan sama dengan jawaban doi. 🤔

Itulah alasan kenapa saya bukan Elon Musk! 😅

Saya bisa saja berdalih, “Dia kan cerdas, pekerja keras, dan punya privilege”. Benar, itu diantaranya! Tapi ingat bahwa di luar sana masih banyak orang cerdas lainnya. Lantas, kenapa hanya ada satu Elon Musk?

Jawabannya mental model!

Mamang Elon memiliki teknik atau mental model dalam membuat suatu keputusan yang mungkin tidak dimiliki oleh orang cerdas lainnya.

Contoh lainnya adalah Richard Feynman seorang fisikawan terkenal yang menerima gelar sarjana dari Massachusetts Institute of Technology (MIT) dan gelar doktor dari Princeton University. Feynman dapat menyelesaikan sebuah soal matematika yang saat itu para mahasiswa doktoral yang cerdas pun tidak dapat menyelesaikannya.

Terbayang sesulit apa soalnya? 😅

Ketika ditanya bagaimana dia dapat melakukannya, Feynman mengatakan bahwa rahasianya bukan pada kecerdasannya melainkan strategi yang dia pelajari ketika di sekolah menengah.

Begini ceritanya…

Saat itu Feynman membaca sebuah buku berjudul “Advanced Calculus”. Menurutnya buku tersebut mengajarkan bagaimana cara membedakan parameter di bawah tanda integral yang ternyata hal itu tidak banyak diajarkan di sekolah-sekolah.

Akhirnya dia mulai mengerti dan menggunakan metode tersebut secara berulang-ulang sehingga Feynman memiliki metode khusus dalam melakukan integral.

“But I caught on how to use that method, and I used that one damn tool again and again. So because I was self-taught using that book, I had peculiar methods of doing integrals.” Richard Feynman

“Ketika orang-orang di MIT dan Princeton mengalami kesulitan melakukan integral tertentu, itu karena mereka tidak dapat melakukannya dengan metode standar yang telah mereka pelajari di sekolah”, ungkapnya.

Setiap mahasiswa doktoral di MIT dan Princeton adalah orang-orang brilian. Apa yang membedakan Feynman dari teman-temannya bukan pada kecerdasannya tetapi dari cara dia melihat masalahnya. Feynman memiliki seperangkat mental model yang lebih luas.

Lalu apa itu mental model?

Pengertian Mental Model

“A mental model is an explanation of someone’s thought process about how something works in the real world.” Wikipedia

Mental model adalah bagaimana cara kita melihat dan memahami sesuatu bekerja, dalam arti lain merupakan cara pandang kita terhadap sesuatu. Mental model membantu kita dalam memecahkan masalah dan membuat sebuah keputusan.

Dengan mempelajari mental model baru memberikan kita cara baru untuk melihat dunia seperti Richard Feynman yang mempelajari teknik matematika baru.

Terdapat banyak jenis mental model pada berbagai bidang seperti ekonomi, psikologi, biologi, kimia, fisika, matematika, dan termasuk bidang pemrograman. Sedangka tulisan ini akan fokus membahasan mental model pada bahasa pemrograman JavaScript.

Mental Model pada JavaScript

Perhatikan baris kode berikut:

let message = 'Hello!';
message = 'World!';

Ketika kita membaca kode di atas secara baris per baris, mungkin di kepala kita akan terdapat monolog seperti ini:

  • let message = 'Hello!';

    • Deklarasikan sebuah variabel bernama message lalu assign nilai 'Hello!'.
  • message = 'World!';

    • Reassign variabel message dengan nilai 'World!'.
    • Ahaaa, saat ini variabel message bernilai 'World!'.

Monolog tersebut merupakan contoh mental model yaitu bagaimana kita melihat atau memahami kode tersebut dieksekusi secara baris per barisnya.

Namun monolog tersebut belum tepat! Tau kenapa?

Karena di dalam JavaScript, pada dasarnya kita tidak meng-assign nilai kepada variabel melainkan variabel itu sendiri yang mem-bind dirinya terhadap nilai. Maksudnya gimana?

Gampangnya begini:

let message = 'Hello!';

// Assign ❌
// message <-- 'Hello!'

// Bind ✅
// message --> 'Hello!'

Tanda panah <-- menunjukkan seakan kita memberikan nilai 'Hello!' kepada variabel message sehingga variabel message memiliki nilai 'Hello!'. Padahal di dalam JavaScript, variabel tidak memiliki atau tidak mengandung nilai.

Oleh karena itu tanda panah --> menunjukkan bahwa variabel message tidak memiliki nilai 'Hello!' akan tetapi hanya mengacu atau mem-bind dirinya terhadap nilai 'Hello!'.

Sehingga monolog yang tepat kira-kira akan seperti ini:

  • let message = 'Hello!';

    • Deklarasikan sebuah variabel dengan nama message lalu bind variabel message ke nilai 'Hello!'.
  • message = 'World!';

    • Rebind variabel message dari nilai 'Hello!' ke nilai 'World!'.
    • Saat ini variabel message mem-bind dirinya ke nilai 'World!'.

Kamu mungkin saja bertanya-tanya, apa manfaatnya? Toh hanya berbeda dari cara penyebutannya saja.

Kenyataannya tidak se-simple itu. Konsep ini merupakan salah satu hal yang fundamental di dalam JavaScript. Dengan mental model yang tepat, kita dapat memahami JavaScript dengan lebih baik.

Mari kita lanjutkan…

Variabel Sebagai Kotak

Ketika berbicara mengenai konsep variabel pada JavaScript, sebagian orang menganalogikan variabel sebagai sebuah kotak yang berlabel dan isi dari kotak tersebut adalah nilainya. Konsep ini sama dengan konsep assign dimana sebuah nilai di-assign kepada sebuah variabel sehingga variabel (kotak) memiliki nilai (isi).

Ilustrasi variabel sebagai kotak
Ilustrasi variabel sebagai kotak

Dengan masih menggunakan contoh yang sama:

let message = 'Hello!';
message = 'World!';

Mental model ini memengaruhi cara kita membaca baris kode di atas menjadi seperti ini:

  • let message = 'Hello!';

    • Siapkan sebuah kotak dengan label message lalu masukkan nilai 'Hello!' ke dalamnya.
  • message = 'World!';

    • Keluarkan nilai 'Hello!' dan masukkan nilai 'World!' ke dalam kotak berlabel message tersebut.
    • Saat ini kotak berlabel message berisi nilai 'World!'.

Variabel Sebagai Tentakel

“To catch and hold values, JavaScript provides a thing called a binding, or variable.” Eloquent JavaScript

Alih-alih menganalogikan variabel sebagai sebuah kotak, Marijn Haverbeke di dalam bukunya “Eloquent JavaScript” menganalogikan variabel sebagai tentakel.

Berbeda dengan konsep variabel sebagai kotak yang sama dengan konsep assign dimana nilai di-assign kepada sebuah variabel sehingga variabel memiliki nilai, konsep variabel sebagai tentakel sama dengan konsep bind dimana variabel tidak memiliki nilai melainkan hanya “menggenggam”-nya (mem-bind).

“You should imagine bindings as tentacles, rather than boxes. They do not contain values; they grasp them—two bindings can refer to the same value.” Eloquent JavaScript

let message = 'Hello!';
message = 'World!';

Jika kembali kepada baris kode di atas, keyword let mendeklarasikan sebuah binding atau variabel dengan nama message. Variabel tersebut digunakan untuk menggenggam nilai 'Hello!' lalu melepasnya, kemudian menggenggam nilai 'World!'.

Penggunaan kata “menggenggam” karena mental model ini menganalogikan variabel sebagai tentakel sehingga ketika membaca baris kode tersebut, monolognya seperti ini:

  • let message = 'Hello!';

    • Sebuah tentakel bertanda message menggenggam nilai 'Hello!'.
  • message = 'World!';

    • Tentakel tersebut melepaskan nilai 'Hello!' dari genggamannya lalu mengenggam nilai 'World!'.
    • Sehingga saat ini tentakel bertanda message menggenggam nilai 'World!'.

Variabel Sebagai Kabel

Dan Abramov salah seorang jagoan JavaScript menganalogikan bahwa variabel merupakan sebuah kabel yang memiliki dua ujung dan satu arah; yaitu dimulai dari nama variabel yang mengacu atau mengarah ke nilai.

let message = 'Hello!';

// Ujung kiri: message
// Ujung kanan: 'Hello!'
// Arah: =

//Note: Tanda `=` merupakan arah `-->` (bind) bukan `<--` (assign)

Mental model ini sama dengan analogi variabel sebagai tentakel dibandingkan dengan variabel sebagai kotak yang menjelaskan bahwa variabel tidak memiliki nilai melainkan hanya terhubung kepada nilai.

let message = 'Hello!';
message = 'World!';

Monolog untuk mental model ini adalah seperti berikut:

  • let message = 'Hello!';

    • Sebuah kabel berlabel message dihubungkan ke nilai 'Hello!'.
  • message = 'World!';

    • Lepaskan kabel tersebut dari nilai 'Hello!' dan hubungkan ke nilai 'World!'.
    • Saat ini kabel berlabel message terhubung ke nilai 'World!'.

JavaScript Sebagai Tata Surya

Dan Abramov juga menganalogikan bahwa JavaScript merupakan sebuah tata surya. Kita berdiri di atas sebuah asteroid yang merupakan kode program kita. Pada permukaannya terdapat if statement, function call, variable declaration, dan lain-lain.

Ingat ya, kode program kita diibaratkan sebagai sebuah asteroid di tata surya JavaScript! Contoh-contoh kode yang berada di dalam program kita, diantaranya:

// Contoh if statement
if (condition) {
  // ...
}

// Contoh function call
getUserStatus();

// Contoh variable declaration
let message;

Lalu values seperti null, undefined, "Hello!", 1, true, {a: 1}, [1, 2, 3] berada di mana?

Nilai-nilai tersebut tidak berada di permukaan asteroid (kode program) kita, melainkan berada di langit JavaScript!

Perhatikan baris kode berikut:

let message = 'Hello!';

Ketika di permukaan asteroid kita terdapat baris kode seperti di atas, itu berarti yang benar-benar terdapat di dalam kode program kita hanya let message sedangkan dari permukaan asteriod, kita hanya mengacu ke langit JavaScript dalam menggunakan Hello!.

Sebagai pengingat bahwa nilai-nilai yang berada di langit JavaScript terbagi dua:

  • Nilai primitif: Undefined, Null, Booleans, Numbers, Strings, Symbols, dan BigInt.
  • Nilai non-primitif: Objects dan Functions.

Nilai primitif seperti 'Hello!' bagaikan bintang-bintang yang jauh. Meski kita dapat menggunakannya tetapi kita tidak dapat mengubahnya atau memanipulasinya karena nilai primitif bersifat read-only.

Sebaliknya nilai non-primitif ibarat bebatuan yang beterbangan di dekat asteroid kita yang menunjukan bahwa nilai-nilai non-primitif dapat kita manipulasi.

Jika disimpulkan seperti ini:
JavaScript = Tata surya 💫
Kode program kita = Asteroid 🌕
Deklarasi variabel = Salah satu yang berada di permukaan asteroid
Nilai primitif = Bintang yang jaraknya sangat jauh dari asteroid
Nilai non-primitif = Bebatuan yang beterbangan di sekitar asteroid

Contoh 1:

'use strict';

let arr = ['a', 'b', 'c'];
let str = 'Hello!';

console.log(arr[0]); // 'a'
console.log(str[0]); // 'H'

// Mengubah salah satu item pada array
arr[0] = 'd';
console.log(arr); // ['d', 'b', 'c'];

// Tetapi kita tidak dapat mengubah karakter pada string
str[0] = 'Y';
console.log(str); // Uncaught TypeError: Cannot assign to read only property '0' of string 'Hello!'

Contoh 2:

let message = 'Hello!';
message = 'World!';

// Kenapa ini berhasil diubah?
console.log(message); // 'World!'

Pada contoh 2, kita tidak sedang mengubah nilai sebuah string akan tetapi mengubah binding sebuah variabel dari string satu ke string lainnya.

Kembali kepada analogi bahwa variabel sebagai kabel. Baris kode tersebut menginstruksikan JavaScript untuk menghubungkan kabel di sisi kiri (variabel message) pada nilai di sisi kanan ('World!'). Kabel tersebut akan terus terhubung pada nilai tersebut sampai kita mengubahnya.

Terdapat 2 aturan terkait hal ini:

  1. Sisi kiri harus merupakan kabel (variabel)
'Hello!' = 'Hello!'; // Uncaught SyntaxError: Invalid left-hand side in assignment

// Contoh yang benar
let hello = 'Hello!'; // Kabel hello terhubung ke nilai 'Hello!'
  1. Sisi kanan harus merupakan ekspresi

Secara singkat, ekspresi adalah pertanyaan yang dapat dijawab oleh JavaScript dengan jawaban berupa nilai.

console.log(2 + 2); // 4

Kita bertanya kepada JavaScript dengan ekspresi 2+2, maka JavaScript menjawab ekspresi tersebut dengan nilai 4.

// 'Hello' merupakan ekspresi
let hello = 'Hello';

// hello + ' world!' juga merupakan ekspresi
let helloWorld = hello + ' world!';

Membaca Nilai Variabel

Perhatikan contoh berikut:

const readValue = function (expression) {
  console.log(expression);
};

let message = 'Hello!';
readValue(message);

Sebagian dari kita mungkin berpikir bahwa variabel message dikirimkan sebagai function argument. Namun kenyataanya tidak demikian!

Kita tidak dapat mengirimkan variabel sebagai argument pada function. Yang terjadi sebenarnya adalah nilai 'Hello!' yang dikirim.

let message = 'Hello!';
readValue(message);

Ternyata nama variabel seperti message juga dapat berfungsi sebagai ekspresi, loh!

Pada bagian readValue(message) dimana kita bertanya kepada JavaScript: “JavaScript, tolong beri tahu bahwa variabel message saat ini terhubung ke nilai apa?“.

Untuk menjawab pertanyaan tersebut, JavaScript menelusuri kabel message ternyata terhubung ke nilai Hello! dan JavaScript memberikan jawaban berupa nilai Hello! sehingga nilai inilah yang dikirim sebagai function argument.

Sehingga dapat kita simpulkan bahwa yang dikirim sebagai function argument adalah nilai atau value bukan variabel karena variabel bukan sebuah nilai.

Untuk membuktikan bahwa yang dikirim sebagai function argument adalah nilai dan bukan variabel. Perhatikan baris kode berikut:

const gandakan = function (uang) {
  uang = uang * 2;
};

let uang = 500;
gandakan(uang);
console.log(uang); // ???

Jika kita berpikir bahwa yang dikirim sebagai function argument adalah variabel, seharusnya fungsi di atas menggandakan variabel uang. Namun yang sebenarnya bahwa gandakan(uang) lagi-lagi kita bertanya terlebih dulu kepada JavaScript bahwa variabel uang terhubung ke nilai apa? Setelah itu JavaScript memberikan jawaban berupa nilai 500 yang kemudian nilai tersebut dikirimkan sebagai function argument” sehingga ketika dijalankan, fungsi tersebut akan mengevaluasi 500 * 2 bukan uang * 2.

Masih berlanjut…