BAB 3: Nilai dan Tipe Data
Angka, string, boolean, null, undefined, dan BigInt -- blok bangunan paling dasar di JavaScript.
Di latihan terakhir Bab 2, kamu menjalankan console.log(typeof "halo") dan console.log(typeof 42) — dan mungkin kamu penasaran mengapa hasilnya berbeda. JavaScript membedakan "halo" dan 42 bukan karena alasan teknis yang rumit, tapi karena keduanya memang jenis nilai yang berbeda. Dan perbedaan jenis ini menentukan apa yang bisa kamu lakukan dengan nilai tersebut.
Di JavaScript, setiap nilai punya tipe — kategori yang memberi tahu engine bagaimana menyimpannya di memori dan operasi apa yang boleh dilakukan padanya. Memahami tipe data bukan hafalan teori — ini adalah fondasi yang langsung berpengaruh setiap kali kamu menulis kode.
Tujuh Tipe Primitif
JavaScript memiliki tujuh tipe data primitif: nilai paling mendasar yang tidak bisa dipecah lebih jauh. Semua tipe lainnya (array, object, function) dibangun di atas fondasi ini.
Operator typeof adalah cara cepat untuk mengecek tipe sebuah nilai:
// eksplorasi-tipe.js
console.log(typeof 42); // "number"
console.log(typeof "halo"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" ← bukan "null", ini bug historis
console.log(typeof 9n); // "bigint"
console.log(typeof Symbol()); // "symbol"
Ketujuh tipe ini punya karakteristik masing-masing yang perlu dipahami satu per satu.
Number
Semua angka di JavaScript — baik integer maupun desimal — disimpan dalam satu tipe yang sama: number. Di balik layar, JavaScript menggunakan format IEEE 754 double-precision 64-bit, format yang sama digunakan oleh bahasa lain seperti Java atau C# untuk tipe double.
// eksplorasi-tipe.js
console.log(42); // integer
console.log(3.14); // desimal
console.log(-17); // negatif
console.log(0.1 + 0.2); // 0.30000000000000004 -- efek samping IEEE 754
Baris terakhir itu sering mengejutkan pemula: 0.1 + 0.2 tidak menghasilkan 0.3 yang "sempurna". Ini bukan bug JavaScript — ini konsekuensi dari cara bilangan desimal direpresentasikan dalam biner. Hampir semua bahasa pemrograman dengan floating point mengalami hal yang sama.
Ada tiga nilai number khusus yang perlu kamu kenal:
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(0 / 0); // NaN
console.log("teks" * 3); // NaN
Infinity muncul ketika angka melampaui batas representasi. NaN (singkatan dari Not-a-Number) muncul saat operasi matematika menghasilkan sesuatu yang bukan angka yang valid. Yang menarik tentang NaN: ia adalah satu-satunya nilai di JavaScript yang tidak sama dengan dirinya sendiri.
console.log(NaN === NaN); // false -- perilaku yang tidak intuitif tapi sengaja
Untuk mengecek apakah sebuah nilai adalah NaN, gunakan fungsi Number.isNaN():
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN("teks")); // false
Batas Presisi Integer
Tipe number hanya bisa merepresentasikan integer dengan presisi sempurna sampai Number.MAX_SAFE_INTEGER, yaitu 253 - 1 atau 9.007.199.254.740.991. Di atas angka itu, precision mulai hilang.
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(9007199254740991 + 1); // 9007199254740992 -- masih benar
console.log(9007199254740991 + 2); // 9007199254740992 -- salah! harusnya ...993
Untuk angka yang melampaui batas ini, ada tipe khusus yang akan dibahas sebentar lagi.
String
String adalah urutan karakter — teks, pada dasarnya. Di JavaScript, string bisa ditulis dengan tiga cara:
// eksplorasi-tipe.js
let pesan1 = "Selamat datang"; // double quote
let pesan2 = 'di JavaScript'; // single quote
let pesan3 = `Bab ${3} dimulai`; // backtick (template literal)
console.log(pesan1); // Selamat datang
console.log(pesan2); // di JavaScript
console.log(pesan3); // Bab 3 dimulai
Single quote dan double quote diperlakukan identik oleh JavaScript — pilih salah satu dan gunakan secara konsisten. Yang menarik adalah template literal (backtick): ia memungkinkan kamu menyisipkan ekspresi JavaScript langsung di dalam string dengan sintaks ${ekspresi}.
let jumlahSiswa = 32;
let namaMatkul = "Pemrograman Web";
console.log(`Mata kuliah ${namaMatkul} diikuti oleh ${jumlahSiswa} siswa.`);
// Mata kuliah Pemrograman Web diikuti oleh 32 siswa.
console.log(`Total nilai: ${85 + 92 + 78}`);
// Total nilai: 255
Template literal juga mendukung string multi-baris tanpa karakter escape khusus:
let pengumuman = `Ujian Tengah Semester
akan dilaksanakan pada
Senin, 20 Maret 2026.`;
console.log(pengumuman);
Biasakan menggunakan template literal untuk string yang mengandung variabel atau ekspresi. Kode jadi lebih mudah dibaca dibanding penggabungan string dengan operator +.
Satu hal penting tentang string: ia bersifat immutable — setelah dibuat, karakter-karakter di dalamnya tidak bisa diubah langsung. Operasi seperti .toUpperCase() tidak mengubah string aslinya, tapi mengembalikan string baru.
Boolean
Tipe ini sederhana: hanya ada dua nilai, true dan false. Boolean adalah hasil dari perbandingan dan kondisi.
// eksplorasi-tipe.js
console.log(5 > 3); // true
console.log(10 === "10"); // false -- tipe berbeda
console.log(7 <= 7); // true
Hampir semua struktur kontrol yang akan kita pelajari di Bab 7 — if, while, dan sejenisnya — bergantung pada nilai boolean untuk menentukan alur program.
Yang perlu diperhatikan: dalam JavaScript, nilai non-boolean bisa "berperilaku" seperti boolean ketika digunakan di kondisi. Nilai yang dianggap false disebut falsy — yaitu 0, "", null, undefined, NaN, dan false itu sendiri. Semua nilai lainnya dianggap truthy.
if (0) {
console.log("ini tidak akan dijalankan");
}
if ("teks") {
console.log("ini akan dijalankan"); // truthy
}
Kita akan menggunakan ini secara ekstensif saat membahas kondisional nanti.
null dan undefined
Keduanya mewakili "ketiadaan nilai", tapi untuk alasan yang berbeda.
undefined adalah nilai default ketika sesuatu belum diinisialisasi. JavaScript yang menetapkan nilai ini secara otomatis:
// eksplorasi-tipe.js
let statusPendaftaran;
console.log(statusPendaftaran); // undefined -- belum diisi
function cetakNama(nama) {
console.log(nama);
}
cetakNama(); // undefined -- parameter tidak diberikan
null adalah nilai yang sengaja diberikan untuk menandai "tidak ada nilai di sini". Ini keputusan programmer, bukan JavaScript:
let dosenPembimbing = null; // sengaja kosong, belum ada dosen yang ditugaskan
Perbedaannya halus tapi penting: undefined artinya "belum diisi", null artinya "sengaja dikosongkan".
typeof null menghasilkan "object", bukan "null". Ini adalah bug historis JavaScript sejak versi pertamanya yang tidak bisa diperbaiki karena akan merusak banyak kode yang sudah ada. Jangan anggap ini sebagai perilaku yang masuk akal — ini adalah kekhasan yang perlu dihafal.
BigInt
Seperti yang terlihat di bagian Number, tipe number biasa memiliki batas presisi untuk integer besar. Di sinilah BigInt masuk — tipe yang dirancang khusus untuk bekerja dengan integer berukuran arbitrari.
Cara membuat BigInt: tambahkan n di akhir angka, atau gunakan fungsi BigInt():
// eksplorasi-tipe.js
const angkaBesar = 9007199254740991n;
const lebihBesar = angkaBesar + 1n;
console.log(lebihBesar); // 9007199254740992n -- presisi sempurna
console.log(typeof angkaBesar); // "bigint"
Ada satu batasan penting: BigInt dan number biasa tidak bisa dicampur langsung dalam operasi aritmatika.
console.log(9n + 1); // TypeError: Cannot mix BigInt and other types
console.log(9n + 1n); // 10n -- harus sama-sama BigInt
Untuk sebagian besar kebutuhan sehari-hari, number biasa sudah lebih dari cukup. BigInt relevan ketika kamu bekerja dengan kriptografi, ID unik yang sangat panjang, atau kalkulasi ilmiah dengan bilangan sangat besar.
Symbol
Symbol adalah tipe primitif yang menghasilkan nilai unik dan tidak bisa disamakan dengan nilai lain — bahkan Symbol lain dengan deskripsi yang sama:
const id1 = Symbol("id");
const id2 = Symbol("id");
console.log(id1 === id2); // false -- selalu berbeda
console.log(typeof id1); // "symbol"
Symbol digunakan terutama sebagai property key unik pada object — untuk menghindari konflik nama. Ini adalah topik lanjutan yang akan relevan ketika kita membahas object dan prototype di bab-bab berikutnya. Untuk sekarang, cukup tahu bahwa Symbol ada dan apa fungsinya.
Latihan
Tiga soal berikut melatih intuisi tentang tipe dan perilaku nilai di JavaScript:
-
Tanpa menjalankan kode, prediksi output dari baris-baris berikut. Kemudian verifikasi di console:
console.log(typeof (1 + "2")); console.log(typeof (true + 1)); console.log(typeof (null + 1));Apa yang bisa kamu simpulkan tentang cara JavaScript menangani operasi antar tipe yang berbeda?
-
Jalankan
0.1 + 0.2 === 0.3di console. Hasilnyafalse. Kemudian cobaMath.abs(0.1 + 0.2 - 0.3) < Number.EPSILON. Apa yang dilakukan ekspresi kedua, dan mengapa ini menjadi cara yang lebih benar untuk membandingkan angka desimal? -
Buat sebuah program kecil yang mendeklarasikan tiga variabel: satu untuk menyimpan nama mahasiswa (string), satu untuk nilai akhir (number), dan satu untuk status kelulusan (boolean berdasarkan nilai >= 60). Tampilkan ketiganya dengan
console.log, lalu tampilkan juga tipe masing-masing menggunakantypeof.
Tipe data memberi kamu gambaran tentang apa yang disimpan JavaScript. Tapi untuk benar-benar bekerja dengan nilai-nilai itu — menambah, membandingkan, menggabungkan — kamu butuh operator. Di bab berikutnya, kita akan menjelajahi seluruh toolkit operator JavaScript: aritmatika, perbandingan, logika, dan beberapa perilaku tak terduga yang akan membuat kamu lebih waspada saat menulis kode.