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.