Berbicara Tentang Undefined, Null, Not Defined dan Undeclared
Dalam Javascript, terdapat beberapa istilah yang sekilas terdengar mirip: undefined, null, not defined dan undeclared. Jika kita baru mendengar istilah-istilah tersebut, mungkin kita akan merasa bahwa semua istilah itu berkaitan erat, bahkan mungkin mereka menjelaskan konsep yang sama. Kenyataannya, terdapat perbedaan - bahkan cukup besar - antara masing-masing istilah tersebut. Mari kita telaah.
Undefined dan Null
Salah satu hal unik di Javascript adalah keberadaan primitive value undefined
di samping null
. Keduanya merepresentasikan hal yang berbeda, di mana null
seperti pada bahasa pemrograman pada umumnya merepresentasikan ketiadaan, sementara undefined
merepresentasikan tidak adanya value.
Sekilas terdengar sama, bukan? Untuk mudahnya, perbedaan paling terlihat adalah penggunanya, di mana undefined
digunakan utamanya oleh engine Javascript sementara null
utamanya digunakan secara sadar oleh programmer. Artinya, ketika kita menemui undefined
, kemungkinan besar itu diakibatkan oleh kesalahan di luar kesengajaan kita seperti syntax error.
Value undefined
digunakan pada variabel yang terdeklarasi tanpa isi nilai, parameter fungsi yang kurang, serta variabel yang tidak dikenal.
// deklarasi variabel tanpa isi
var a;
console.log(a); // undefined
var a = undefined; // pola seperti ini berarti no-op
// parameter fungsi yang kurang
function foo(bar, baz) {
console.log(bar, baz);
}
foo("hai"); // "hai" undefined
// variabel yang tidak dikenal
var obj = { a: 1 };
console.log(obj.b); // undefined
Sementara null
tersedia bagi developer untuk mengindikasikan ketiadaan nilai pada variabel. Contoh kasus penggunaan null
adalah pada nilai default parameter sebuah fungsi.
function foo(bar, baz = null) {
// ...
if (baz !== null) { // ... }
}
Coercion Null dan Undefined
Baik null
maupun undefined
memiliki tipe datanya sendiri. Oleh karena itu, keduanya memiliki peraturan coercion tersendiri.
Keduanya termasuk ke dalam false-y values pada Javascript. Artinya, jika kita memberlakukan operasi Boolean terhadapnya, mereka akan dianggap memiliki nilai false
. Contohnya apabila kita melakukan cast-to-bool dengan operator !!
(saya suka menyebutnya "bang, bang, you're Boolean!"):
console.log(!!null); //false
console.log(!!undefined); //false
Sampai sini, mereka terdengar sangat mirip, bukan? Apalagi jika kita melakukan penyamaan kedua nilai tersebut:
null == undefined // true
Namun, ketika kita menggunakan operator strict equality, hasilnya akan berbeda:
null === undefined // false
Hal ini dikarenakan, seperti yang saya utarakan sebelumnya, baik null
maupun undefined
adalah value ekslusif dari tipe datanya masing-masing, sehingga strictly speaking, keduanya adalah dua hal yang berbeda.
typeof undefined; // "undefined"
typeof null;// "object"
/*
** NOTE: tipe data null yang berupa objek adalah bug dalam Javascript,
** seharusnya tipe data null adalah null juga. Bug ini sengaja diabaikan
** untuk menjamin backward compatibility.
**/
Caveat Pengecekan Undefined
Pengecekan terhadap value undefined
dapat dilakukan dengan tiga cara:
var x;
// cara pertama
x === undefined;
// cara kedua
typeof x === 'undefined';
// cara ketiga
x === void 0;
Cara yang salah adalah dengan menggunakan bang, misalnya if (!x) { //... }
, karena jika x
sesungguhnya tidak bernilai undefined
namun bernilai sesuatu yang false-y seperti ""
, "0"
, atau bahkan null
, maka x
akan lolos pengecekan.
Yang perlu sangat diperhatikan di sini adalah pengecekan dengan menggunakan operator typeof
. Misalkan kita melakukan pengecekan variabel foo
. Jika foo
belum dideklarasikan, maka tanpa menggunakan typeof
, pengecekan akan melempar Uncaught ReferenceError: foo is not defined
. Perhatikan juga bahwa kembalian operator typeof
adalah String.
typeof foo === 'undefined'; // true
foo === undefined; // Uncaught ReferenceError: foo is not defined
Undefined atau Not Defined?
Sempat disebut suatu error dengan pesan foo is not defined
. Meskipun terdengar sama, undefined
dan not defined
adalah dua hal yang berbeda. Ketika sebuah variabel dikatakan not defined
, artinya variabel tersebut tidak eksis alias belum dideklarasikan pada saat pemanggilannya.
var foo;
foo === undefined; // true
bar === undefined; // Uncaught ReferenceError: bar is not defined
Saya pribadi merasa error tersebut lebih cocok disebut not declared
.
Undeclared Variable
Setelah undefined
dan not defined
, ada lagi yang disebut undeclared variable
. Meskipun terdengar mirip, frasa ini menjelaskan fenomena yang sama sekali berbeda.
Suatu variabel dikatakan undeclared variable ketika ia diinisiasi tanpa menggunakan keyword deklarasi variabel seperti var
, const
ataupun let
.
Ketika kita melakukan itu, katakanlah dengan nama variabel foo
Javascript akan mencari tahu apakah foo
sudah terdeklarasi. Pencarian dimulai dari scope tempat ekspresi foo
berada terus ke atas hingga global scope. Jika hingga global scope tidak ditemukan deklarasi foo
, maka Javascript akan membuatkan foo
untuk Anda di global scope. Untuk lebih jelasnya perhatikan contoh di bawah ini:
function foo() {
var x = 10;
function bar() {
x = 15;
y = 2;
console.log(x); // 15
console.log(y); // 2
}
x += 5;
console.log(x); // 20
}
foo();
console.log(y); // 2
window.hasOwnProperty(y); // true
// padahal kita tidak pernah mendeklarasikan y pada global scope
Terdapat dua undeclared variable pada fungsi bar
, yaitu x
dan y
. Mencari ke atas, ditemukan deklarasi x
pada scope fungsi foo
, sehingga yang terjadi adalah penetapan kembali nilai x
menjadi 15
. Maka sesungguhnya x
yang dilempar ke console.log
pada fungsi bar
adalah x
milik foo
. Itulah sebabnya ketika kita lakukan x += 5
di bawah, nilai x
malah menjadi 20
alih-alih 15
.
Untuk variabel y
, karena ketika dicari ke atas tidak ditemukan deklarasinya hingga global scope, maka Javascript membuatkan sebuah global variable y
yang berisi 2
untuk kita. Kejadian ini kerap disebut global variable leak.
Kebocoran variabel hingga ke global scope dapat menjadi ancaman nyata bagi kode Anda. Selain menambahkan variabel global secara tidak disadari, keberadaan undeclared variable seperti ini dapat membuat perilaku kode Anda semakin tidak dapat diprediksi. Hindari kejadian ini dengan lebih teliti mendeklarasikan variabel pada tiap-tiap scope Anda.
Semoga tulisan ini dapat memberikan pencerahan tentang undefined
, null
, not defined, dan undeclared variable. Jika Anda memiliki tambahan, sanggahan ataupun pertanyaan, silakan meninggalkan komentar pada kolom di bawah.