Masukkan Password
56 Value Type vs Reference Type
Lecture ini sangat penting, karena konsep value type vs reference type akan menjelaskan kenapa kadang-kadang ketika kita menyalin sebuah variable, perubahan pada satu variable tidak memengaruhi variable lain, tetapi pada kasus object justru bisa saling memengaruhi.
Kalau bagian ini belum benar-benar dipahami, nanti kamu akan cukup sering bingung dengan:
- object
- array
- function
=- copy
- mutation
null- garbage collection
- dan bahkan
const
Jadi kita pelajari pelan-pelan.
1. Gambaran besarnya dulu
JavaScript bisa mengelompokkan data dengan dua cara berbeda.
Berdasarkan jenis datanya
Primitive
↓
Number
String
Boolean
Undefined
Null
BigInt
Symbol
Object
↓
Object
Array
Function
dll.
Berdasarkan cara data disimpan/direferensikan
Value Type
↓
Primitive values
Reference Type
↓
Objects
Arrays
Functions
Jadi ada hubungan:
Primitive
↓
Value Type
Object
Array
Function
↓
Reference Type
Ini adalah mental model utama lecture.
2. Ingat 7 primitive data types
Sebelumnya kamu sudah belajar bahwa JavaScript mempunyai 7 primitive types:
1. Number
2. String
3. Boolean
4. Undefined
5. Null
6. BigInt
7. Symbol
Contoh:
let age = 30;
30 adalah:
Number
↓
Primitive
↓
Value type
Contoh:
let name = "John";
"John" adalah:
String
↓
Primitive
↓
Value type
Contoh:
let isActive = true;
true adalah:
Boolean
↓
Primitive
↓
Value type
3. Object termasuk reference type
Selain primitive, kita punya object.
Contoh:
const person = {
name: "John",
age: 28
};
person mengacu pada object.
Object adalah:
Object
↓
Reference Type
Begitu juga array:
const numbers = [10, 20, 30];
Array termasuk object dalam JavaScript.
Jadi:
Array
↓
Object
↓
Reference Type
Function juga secara teknis merupakan object:
function greet() {
console.log("Hello");
}
Jadi:
Function
↓
Object
↓
Reference Type
4. Apa itu Value Type?
Sekarang masuk ke konsep utama.
Value type berarti secara sederhana:
Ketika sebuah variable diberi value primitive, yang disalin ketika assignment adalah nilai tersebut.
Contoh:
let x = 30;
let y = x;
Kita punya:
x = 30
Kemudian:
let y = x;
Artinya:
ambil nilai x
↓
30
↓
salin ke y
Hasil:
x = 30
y = 30
5. Kalau x berubah, y bagaimana?
Misalnya:
let x = 30;
let y = x;
x = 100;
Sekarang:
x = 100
y = 30
Kenapa y tidak berubah?
Karena ketika:
let y = x;
yang disalin adalah value.
Jadi y mendapatkan salinan nilai 30.
Setelah itu:
x = 100;
kita mengganti value yang digunakan oleh x.
Tidak ada hubungan antara x dan y.
6. Visualisasi Value Type
Bayangkan:
let x = 30;
let y = x;
Secara sederhana:
x
↓
30
y
↓
30
Setelah:
x = 100;
menjadi:
x
↓
100
y
↓
30
y tetap 30.
7. Analogi fotokopi
Bayangkan kamu punya kertas:
x = 30
Kemudian kamu fotokopi isinya untuk y.
Original:
x → 30
Copy:
y → 30
Kalau kamu mengubah kertas milik x:
x → 100
kertas y tetap:
y → 30
Karena yang kamu copy adalah isinya, bukan hubungan ke kertas yang sama.
Ini gambaran sederhana dari value type.
8. Sekarang masuk Reference Type
Sekarang kita buat object:
let obj1 = {
name: "John",
age: 28
};
Kemudian:
let obj2 = obj1;
Sekilas mungkin kita berpikir:
obj1 → object
obj2 → copy object
Tetapi bukan itu yang terjadi.
Yang terjadi secara konsep:
obj1 → reference → object
obj2 → reference → object
Keduanya mengarah ke object yang sama.
9. Visualisasi Reference Type
Misalnya:
let obj1 = {
name: "John",
age: 28
};
let obj2 = obj1;
Bayangkan:
STACK HEAP
obj1 ───────────────┐
│
↓
┌───────────────┐
│ name: "John" │
│ age: 28 │
└───────────────┘
↑
│
obj2 ───────────────┘
Perhatikan:
obj1 dan obj2 bukan memiliki dua object.
Mereka menunjuk ke object yang sama.
10. Sekarang kita ubah obj2.age
obj2.age = 30;
Apa yang terjadi?
obj2 menunjuk ke object yang sama.
Jadi kita sebenarnya mengubah:
object yang ditunjuk obj2
Object tersebut juga ditunjuk oleh obj1.
Maka:
console.log(obj1.age);
hasilnya:
30
Dan:
console.log(obj2.age);
juga:
30
11. Kenapa obj1 ikut berubah?
Ini pertanyaan paling penting.
Karena:
let obj2 = obj1;
tidak membuat object baru.
Yang dibuat adalah reference baru menuju object yang sama.
Visualisasinya:
┌───────────────┐
obj1 ───────→│ │
│ name: "John" │
obj2 ───────→│ age: 28 │
│ │
└───────────────┘
Kemudian:
obj2.age = 30;
menjadi:
┌───────────────┐
obj1 ───────→│ │
│ name: "John" │
obj2 ───────→│ age: 30 │
│ │
└───────────────┘
Object-nya satu.
Jadi siapa pun yang mengakses object tersebut akan melihat:
age = 30
12. Ini perbedaan paling penting dari lecture
Bandingkan:
Primitive
let x = 30;
let y = x;
x → 30
y → 30
Kemudian:
x = 100;
x → 100
y → 30
Object
let obj1 = {
age: 28
};
let obj2 = obj1;
obj1 ──┐
↓
object
↑
obj2 ──┘
Kemudian:
obj2.age = 30;
obj1 ──┐
↓
age: 30
↑
obj2 ──┘
Jadi:
Value Type
→ copy value
Reference Type
→ copy reference
Ini inti utama lecture.
13. “Reference” itu apa?
Reference bisa kamu bayangkan seperti alamat rumah.
Misalnya object berada di suatu lokasi:
Memory Address: 0xABC123
obj1 menyimpan informasi yang mengarah ke alamat tersebut.
obj1
↓
0xABC123
obj2 = obj1 membuat:
obj2
↓
0xABC123
Maka:
obj1 ──→ 0xABC123
obj2 ──→ 0xABC123
Di alamat tersebut ada:
{
name: "John",
age: 28
}
Jadi dua variable memiliki reference ke object yang sama.
14. Analogi alamat rumah
Bayangkan ada rumah:
Rumah John
Alamat:
Jl. JavaScript No. 30
Kemudian:
obj1 = alamat rumah
obj2 = obj1
Sekarang:
obj1 → Jl. JavaScript No. 30
obj2 → Jl. JavaScript No. 30
Kalau kamu melalui obj2 lalu mengecat rumah menjadi biru:
obj2 → cat rumah biru
Ketika obj1 melihat rumah tersebut:
obj1 → rumah biru
Karena rumahnya satu.
15. Tapi ada satu hal yang sangat penting
Ada perbedaan antara:
Mengubah isi object
dan
Mengganti object yang direferensikan variable
Ini sering membingungkan.
Misalnya:
let obj1 = {
age: 28
};
let obj2 = obj1;
Keduanya:
obj1 ──┐
↓
Object A
↑
obj2 ──┘
Kalau:
obj2.age = 30;
kita memodifikasi Object A.
Maka:
obj1 → Object A → age 30
obj2 → Object A → age 30
16. Kalau kita assign object baru ke obj2?
Misalnya:
obj2 = {
age: 50
};
Ini berbeda.
Sekarang kita membuat object baru.
Object A
{
age: 30
}
↑
│
obj1
Object B
{
age: 50
}
↑
│
obj2
Jadi sekarang obj1 dan obj2 tidak lagi menunjuk object yang sama.
17. Ini contoh yang sangat penting
let obj1 = {
age: 28
};
let obj2 = obj1;
obj2.age = 30;
console.log(obj1.age);
console.log(obj2.age);
Hasil:
30
30
Karena object yang sama dimodifikasi.
Tetapi:
let obj1 = {
age: 28
};
let obj2 = obj1;
obj2 = {
age: 30
};
console.log(obj1.age);
console.log(obj2.age);
Hasil:
28
30
Kenapa?
Karena:
obj2 = {
age: 30
};
bukan mengubah Object A.
Ini membuat Object B baru, kemudian obj2 diarahkan ke Object B.
18. Visualisasinya
Awalnya:
obj1 ──┐
↓
Object A
age: 28
↑
obj2 ──┘
Setelah:
obj2 = {
age: 30
};
menjadi:
obj1 ─────→ Object A
age: 28
obj2 ─────→ Object B
age: 30
Jadi:
Mengubah property
↓
object yang sama berubah
Assign object baru
↓
reference variable berubah
19. Bagaimana dengan Array?
Array juga reference type.
Misalnya:
let arr1 = [10, 20, 30];
let arr2 = arr1;
Keduanya mengarah ke array yang sama:
arr1 ──┐
↓
[10,20,30]
↑
arr2 ──┘
Kalau:
arr2.push(40);
maka:
arr1 → [10, 20, 30, 40]
arr2 → [10, 20, 30, 40]
Karena push() memodifikasi array yang sama.
20. Function juga reference type
Function juga termasuk object/reference type.
Misalnya:
function greet() {
console.log("Hello");
}
let anotherGreet = greet;
Secara konsep:
greet ─────────┐
↓
Function Object
↑
anotherGreet ──┘
Jadi:
anotherGreet();
menjalankan function yang sama.
21. Sekarang masuk ke Stack dan Heap
Lecture kemudian memperkenalkan:
Stack
Heap
Untuk memahami model mental sederhana, anggap:
Stack
↓
menyimpan primitive values dan references/binding terkait variable
Heap
↓
tempat object/array/function disimpan
Contoh:
let x = 30;
Secara model sederhana:
STACK
x → 30
Sedangkan:
let person = {
name: "John"
};
secara model sederhana:
STACK HEAP
person ─────────────→ { name: "John" }
Jadi variable person menyimpan reference menuju object.
22. Tapi hati-hati dengan model Stack vs Heap
Ini penting sebagai catatan teknis.
Lecture menggambarkan seolah-olah:
primitive pasti Stack, object pasti Heap.
Untuk belajar dasar, model ini berguna.
Tetapi secara spesifikasi ECMAScript, JavaScript tidak menetapkan secara eksplisit bahwa semua primitive harus disimpan di stack dan semua object harus disimpan di heap.
Itu adalah detail implementasi engine JavaScript.
Jadi untuk sekarang gunakan model:
Primitive
→ value semantics
Object
→ reference semantics
Itu jauh lebih penting daripada menghafal detail fisik memory.
23. “Memory address” juga adalah model mental
Lecture mengatakan variable reference menyimpan memory address.
Untuk pemula, ini sangat membantu.
Kamu bisa membayangkan:
obj1
↓
alamat 0x123
↓
object
Tetapi jangan menganggap JavaScript memberikan kita akses langsung ke alamat memory seperti bahasa tingkat rendah.
Kita tidak bisa melakukan:
console.log(0x123);
untuk mengambil alamat object.
Jadi “memory address” di sini adalah model untuk memahami reference, bukan API yang bisa kita manipulasi langsung.
24. Bagian menarik: obj1 = null
Lecture kemudian melakukan:
obj1 = null;
Apa artinya?
Sebelumnya:
obj1 ──→ Object
Setelah:
obj1 = null;
menjadi:
obj1 → null
Artinya obj1 sekarang tidak lagi mereferensikan object tersebut.
25. Kalau masih ada obj2 bagaimana?
Misalnya:
let obj1 = {
name: "John"
};
let obj2 = obj1;
obj1 = null;
Sekarang:
obj1 → null
obj2 ─────→ Object
Object masih bisa diakses melalui obj2.
Jadi object belum menjadi tidak terjangkau.
26. Kalau obj2 juga dibuat null?
Misalnya:
obj1 = null;
obj2 = null;
Sekarang:
obj1 → null
obj2 → null
Object
↑
tidak ada reference lagi
Object tersebut sekarang tidak lagi reachable dari program melalui reference yang aktif.
Pada kondisi seperti ini, object pada akhirnya bisa dibersihkan oleh:
Garbage Collector
27. Apa itu Garbage Collector?
JavaScript mempunyai mekanisme otomatis untuk membersihkan memory yang sudah tidak diperlukan.
Bayangkan:
Object
↑
tidak ada variable yang
bisa mengaksesnya
Object tersebut menjadi unreachable.
Garbage Collector nantinya dapat mendeteksi bahwa object tersebut tidak lagi digunakan dan membebaskan memory-nya.
Secara sederhana:
Object masih digunakan
↓
jangan hapus
Object sudah unreachable
↓
boleh dibersihkan
↓
Garbage Collector
28. Jangan berpikir garbage collector langsung bekerja
Misalnya:
obj1 = null;
obj2 = null;
Bukan berarti:
“Object langsung dihapus saat baris tersebut dijalankan.”
Lebih tepat:
Object menjadi eligible for garbage collection jika memang sudah tidak reachable.
Kapan tepatnya garbage collector berjalan merupakan urusan JavaScript engine.
29. Ini alasan reference type penting
Sekarang bayangkan kamu punya:
const user = {
name: "John",
age: 28
};
Kemudian:
const anotherUser = user;
Kamu mungkin berpikir:
“Saya sudah membuat copy user.”
Padahal:
anotherUser
↓
reference yang sama
↓
object user
Jadi kalau kamu melakukan:
anotherUser.age = 30;
maka:
console.log(user.age);
akan menjadi:
30
Kalau kamu tidak memahami reference type, hasil ini bisa terasa seperti bug.
30. Ini sering disebut “shallow copy” vs “reference sharing”
Untuk kasus:
let obj2 = obj1;
secara sederhana kita bisa mengatakan:
Tidak terjadi copy object. Reference-nya yang disalin.
Kalau kita benar-benar ingin membuat object baru yang terpisah, kita perlu menggunakan teknik copy seperti:
const obj2 = { ...obj1 };
atau:
const obj2 = Object.assign({}, obj1);
Untuk object sederhana, ini membuat object baru.
Contoh:
const obj1 = {
name: "John",
age: 28
};
const obj2 = {
...obj1
};
obj2.age = 30;
Sekarang:
obj1.age → 28
obj2.age → 30
Karena object-nya berbeda.
Catatan: spread hanya melakukan shallow copy. Kalau object memiliki nested object, konsepnya menjadi lebih dalam. Itu bisa kita bahas nanti saat course sampai ke sana.
31. Hubungan dengan const
Ini juga akan sangat berguna karena kamu sebelumnya belajar const.
Perhatikan:
const person = {
name: "John"
};
Kita masih boleh:
person.name = "Mark";
Mengapa?
Karena const melarang reassignment variable, bukan melarang perubahan isi object.
Secara mental:
person
↓
reference
↓
Object
const berarti:
Reference yang disimpan oleh
persontidak boleh diganti.
Tetapi isi object masih bisa dimodifikasi.
Jadi ini boleh:
person.name = "Mark";
Tetapi ini tidak boleh:
person = {
name: "Mark"
};
Karena yang kedua mencoba mengganti reference person ke object baru.
32. Ini menghubungkan tiga lecture sekaligus
Sekarang konsep-konsep sebelumnya mulai saling terhubung.
Lecture variable
const person = ...
Lecture object
{
name: "John"
}
Lecture value/reference
person
↓
reference
↓
object
Lecture const
reference tidak boleh diganti
Tetapi:
object masih bisa dimodifikasi
Ini alasan memahami reference type sangat penting.
33. Perbandingan Value vs Reference
| Value Type | Reference Type | |
|---|---|---|
| Contoh | Number, String, Boolean | Object, Array, Function |
| Yang disalin saat assignment | Value | Reference |
| Data object yang sama? | ❌ | Bisa iya |
| Perubahan isi memengaruhi variable lain? | Tidak | Bisa iya |
| Contoh | let y = x | let obj2 = obj1 |
34. Contoh perbandingan langsung
Value
let a = 10;
let b = a;
a = 20;
console.log(a); // 20
console.log(b); // 10
Mental model:
a → 10
b → 10
a → 20
b → 10
Reference
let a = {
value: 10
};
let b = a;
a.value = 20;
console.log(a.value); // 20
console.log(b.value); // 20
Mental model:
a ──┐
↓
Object
value: 20
↑
b ──┘
35. Cara mudah mengingatnya
Gunakan kata:
VALUE = fotokopi isi
REFERENCE = fotokopi alamat
Contoh:
Value Type:
x → 30
↓
copy
↓
y → 30
Sedangkan:
Reference Type:
obj1 → alamat object
↑
copy
↑
obj2 → alamat object
Jadi:
VALUE
↓
copy nilai
REFERENCE
↓
copy referensi
36. Hati-hati: “reference type” bukan berarti variable menyimpan object langsung
Lecture mengatakan variable reference type menyimpan reference.
Mental model:
STACK HEAP
obj1 ──────────────→ Object
Jadi jangan membayangkan:
obj1
↓
{
name: "John"
}
seolah-olah object itu sendiri berada di dalam variable.
Lebih baik bayangkan:
obj1
↓
reference
↓
object
37. Bagaimana dengan String?
String adalah primitive.
let a = "Hello";
let b = a;
a = "World";
Hasil:
a → "World"
b → "Hello"
Walaupun string sebenarnya merupakan object-like dalam banyak penggunaan karena punya property/method seperti:
"hello".toUpperCase()
String tetap primitive type.
38. Bagaimana dengan null?
null termasuk primitive type.
Jadi secara klasifikasi:
null
↓
Primitive
↓
Value type
Walaupun:
typeof null
menghasilkan:
"object"
Itu adalah historical quirk JavaScript.
Jangan sampai ini membuat kamu berpikir null adalah object.
39. Satu koreksi teknis penting dari lecture
Lecture mengatakan kira-kira:
“All primitive values are stored in Stack, and objects in Heap.”
Untuk mental model beginner, tidak masalah menggunakan gambaran tersebut.
Tetapi secara teknis, JavaScript specification tidak memaksa engine menggunakan stack/heap dengan cara tersebut.
Yang benar-benar penting adalah semantics:
Primitive
→ value semantics
Object
→ reference semantics
Dan ini adalah konsep yang akan kamu gunakan ketika coding.
40. Contoh soal yang mungkin muncul
Perhatikan:
let x = 10;
let y = x;
x = 20;
console.log(y);
Jawaban:
10
Karena Number → primitive/value type.
Sekarang:
let x = {
value: 10
};
let y = x;
x.value = 20;
console.log(y.value);
Jawaban:
20
Karena x dan y mengarah ke object yang sama.
41. Contoh lain yang sangat penting
let obj1 = {
name: "John"
};
let obj2 = obj1;
obj2.name = "Mark";
console.log(obj1.name);
Jawaban:
Mark
Bukan John.
Karena:
obj1 ──┐
↓
Object
name: Mark
↑
obj2 ──┘
42. Tetapi ini berbeda
let obj1 = {
name: "John"
};
let obj2 = {
...obj1
};
obj2.name = "Mark";
console.log(obj1.name);
Hasil:
John
Karena:
obj1 → Object A
obj2 → Object B
Object-nya berbeda.
43. Flow keseluruhan lecture
Sekarang kita gabungkan semuanya:
DATA JAVASCRIPT
│
┌─────────┴─────────┐
↓ ↓
Primitive Object
│ │
↓ ↓
Value Type Reference Type
│ │
↓ ↓
copy VALUE copy REFERENCE
│ │
↓ ↓
variable terpisah bisa menunjuk
object yang sama
Contohnya:
VALUE TYPE
x → 30
│
└──copy──→ y → 30
REFERENCE TYPE
obj1 ──┐
↓
Object
↑
obj2 ──┘
44. Cheat sheet untuk kamu
Primitive → Value Type
Number
String
Boolean
Undefined
Null
BigInt
Symbol
Semua:
Primitive
↓
Value Type
↓
copy value
Object → Reference Type
Object
Array
Function
Semua:
Object
↓
Reference Type
↓
copy reference
🧠 Inti yang harus benar-benar kamu ingat
Kalau lecture ini diringkas menjadi 4 kalimat, ingat ini:
1. Primitive values seperti Number, String, dan Boolean menggunakan value semantics.
2. Object, Array, dan Function menggunakan reference semantics.
3. Saat primitive di-assign ke variable lain, nilai/value-nya disalin sehingga keduanya independen.
4. Saat object di-assign ke variable lain, reference-nya yang disalin sehingga dua variable bisa menunjuk object yang sama.
Visual paling penting:
VALUE TYPE
x ──→ 30
y ──→ 30
x berubah
↓
x ──→ 100
y ──→ 30
vs.
REFERENCE TYPE
obj1 ──┐
↓
OBJECT
↑
obj2 ──┘
obj2.age = 30
↓
OBJECT berubah
↓
obj1.age juga 30
Dan satu kalimat yang sangat berguna ketika nanti kamu menemukan bug:
Kalau primitive di-copy, saya mendapatkan value baru. Kalau object di-copy dengan
=, saya hanya mendapatkan reference ke object yang sama.
Itulah alasan value type vs reference type menjadi fondasi penting sebelum kamu belajar copy object, spread operator, destructuring, shallow/deep copy, mutation, dan garbage collection.