Variabel

Variabel adalah struktur data yang menetapkan nama representatif ke sebuah nilai. Mereka dapat berisi data apa pun.

Nama variabel disebut ID. ID yang valid harus mengikuti aturan tersebut:

  • ID dapat berisi huruf Unicode, tanda dolar ($), garis bawah karakter (_), angka (0-9), dan bahkan beberapa karakter Unicode.
  • ID tidak boleh berisi spasi kosong, karena parser menggunakan spasi kosong untuk elemen input terpisah. Misalnya, jika Anda mencoba memanggil variabel my Variable, bukan myVariable, parser akan melihat dua ID, my dan Variable, serta menampilkan error sintaksis ("token yang tidak terduga: ").
  • ID harus diawali dengan huruf, garis bawah (_), atau tanda dolar ($). Mereka tidak boleh dimulai dengan angka, untuk mencegah kebingungan antara angka dan pengenal:

    let 1a = true;
    
    > Uncaught SyntaxError: Invalid or unexpected token
    

    Jika JavaScript mengizinkan angka di awal ID, hal itu akan memungkinkan pengidentifikasi yang hanya terdiri dari angka, yang menyebabkan konflik antar angka yang digunakan sebagai angka dan bilangan yang digunakan sebagai pengenal:

    let 10 = 20
    
    10 + 5
    > ?
    
  • "Kata yang dicadangkan" yang sudah bermakna secara sintaksis tidak dapat digunakan sebagai pengidentifikasi.

  • ID tidak boleh berisi karakter khusus (! . , / \ + - * =).

Berikut ini bukan aturan ketat untuk membuat ID, tetapi praktik terbaik industri yang mempermudah pemeliharaan kode Anda. Jika tujuan proyek memiliki standar yang berbeda, ikutilah itu sebagai gantinya untuk konsistensi.

Dengan mengikuti contoh yang ditetapkan oleh metode dan properti bawaan JavaScript, camelcase (juga bergaya "camelCase") adalah konvensi yang sangat umum untuk pengenal yang terdiri dari beberapa kata. {i>Camel case<i} adalah praktik dari kapitalisasi pada huruf pertama setiap kata kecuali yang pertama untuk keterbacaan tanpa spasi.

let camelCasedIdentifier = true;

Beberapa proyek menggunakan konvensi penamaan lainnya tergantung pada konteks dan sifat data. Misalnya, huruf pertama class biasanya menggunakan huruf besar, jadi nama kelas dengan beberapa kata sering menggunakan varian camel huruf besar/kecil yang biasa disebut "{i>upper camel case<i}" atau Kasus Pascal.

class MyClass {

}

Pengidentifikasi harus secara ringkas menggambarkan sifat data yang dikandungnya (untuk contoh, currentMonthDays adalah nama yang lebih baik daripada theNumberOfDaysInTheCurrentMonth) dan membaca sekilas dengan jelas (originalValue lebih baik daripada val). Tujuan ID myVariable yang digunakan di seluruh modul ini berfungsi dalam konteks contoh yang terpisah, tetapi akan sangat tidak membantu dalam kode produksi karena mereka tidak memberikan informasi tentang data apa yang ada di dalamnya.

Pengidentifikasi tidak boleh terlalu spesifik tentang data yang ada di dalamnya, karena nilai-nilai mereka dapat berubah tergantung pada bagaimana skrip bertindak pada data itu, atau pada keputusan yang dibuat oleh pengelola di masa depan. Misalnya, variabel yang awalnya mengingat ID miles mungkin perlu diubah menjadi nilai dalam kilometer proyek, membutuhkan pengelola untuk mengubah referensi ke variabel itu untuk menghindari kebingungan di masa depan. Untuk mencegah hal ini, gunakan distance sebagai ID Anda sebagai gantinya.

JavaScript tidak memberikan hak istimewa atau arti khusus pada ID yang diawali dengan karakter garis bawah (_), tetapi biasanya digunakan untuk menunjukkan variabel, metode, atau properti adalah "{i>private<i}", artinya itu hanya dimaksudkan untuk digunakan dalam konteks objek yang memuatnya, dan tidak boleh diakses atau dimodifikasi di luar konteks tersebut. Ini adalah konvensi yang dibawa dari bahasa pemrograman lain, dan mendahului penggunaan bahasa pemrograman properti pribadi.

Deklarasi variabel

Ada beberapa cara untuk membuat JavaScript mengenali sebuah pengidentifikasi, yaitu sebuah proses yang disebut “deklarasi” suatu variabel. Variabel dideklarasikan menggunakan let, const, atau var kata kunci.

let myVariable;

Gunakan let atau var untuk mendeklarasikan variabel yang dapat diubah kapan saja. Ini kata kunci memberi tahu penerjemah JavaScript bahwa string karakter adalah yang mungkin berisi nilai.

Saat bekerja di codebase modern, gunakan let, bukan var. var masih berfungsi di {i>browser<i} modern, namun ia memiliki beberapa perilaku yang tidak intuitif seperti yang didefinisikan dalam versi paling awal dari JavaScript, dan kemudian tidak dapat diubah lagi untuk mempertahankan kompatibilitas mundur. let telah ditambahkan di ES6 untuk mengatasi beberapa masalah dengan desain var.

Variabel yang dideklarasikan diinisialisasi dengan menetapkan nilai ke variabel tersebut. Gunakan tanda sama dengan (=) untuk menetapkan atau menetapkan ulang nilai ke variabel. Anda dapat melakukan ini sebagai bagian dari pernyataan yang sama yang mendeklarasikannya:

let myVariable = 5;

myVariable + myVariable
> 10

Anda juga dapat mendeklarasikan variabel dengan let (atau var) tanpa menginisialisasinya saat itu juga. Jika ya, nilai awal variabel tersebut adalah undefined sampai kode menetapkan suatu nilai.

let myVariable;

myVariable;
> undefined

myVariable = 5;

myVariable + myVariable
> 10

Variabel dengan nilai undefined berbeda dengan variabel yang tidak ditentukan yang ID-nya belum dideklarasikan. Mereferensikan variabel yang belum Anda dideklarasikan akan menyebabkan {i>error<i}.

myVariable
> Uncaught ReferenceError: myVariable is not defined

let myVariable;

myVariable
> undefined

Pengaitan ID dengan nilai umumnya disebut "binding". Sintaksis yang mengikuti kata kunci let, var, atau const disebut "daftar binding", dan memungkinkan beberapa deklarasi variabel yang dipisahkan koma (diakhiri dengan titik koma yang diharapkan). Ini membuat cuplikan kode berikut identik secara fungsional:

let firstVariable,
     secondVariable,
     thirdVariable;
let firstVariable;
let secondVariable;
let thirdVariable;

Menetapkan ulang nilai variabel tidak menggunakan let (atau var), karena JavaScript sudah mengetahui bahwa variabel tersebut ada:

let myVariable = true;

myVariable
> true

myVariable = false;

myVariable
> false

Anda dapat menetapkan ulang variabel ke nilai baru berdasarkan nilainya yang sudah ada:

let myVariable = 10;

myVariable
> 10

myVariable = myVariable * myVariable;

myVariable
> 100

Jika Anda mencoba mendeklarasikan ulang variabel menggunakan let di lingkungan produksi, Anda akan mengalami {i>error <i}pada {i>syntax<i}:

let myVariable = true;
let myVariable = false;
> Uncaught SyntaxError: redeclaration of let myVariable

Browser alat developer lebih permisif tentang deklarasi ulang let (dan class), sehingga Anda mungkin tidak melihat error yang sama di konsol developer Anda.

Untuk mempertahankan kompatibilitas browser lama, var memungkinkan deklarasi ulang yang tidak perlu tanpa kesalahan dalam konteks apa pun:

var myVariable = true;
var myVariable = false;

myVariable\
> false

const

Gunakan kata kunci const untuk mendeklarasikan konstanta, jenis variabel yang harus segera diinisialisasi, dan tidak dapat diubah. ID untuk konstanta ikuti semua aturan yang sama seperti variabel yang dideklarasikan menggunakan let (dan var):

const myConstant = true;

myConstant
> true

Anda tidak dapat mendeklarasikan konstanta tanpa segera menetapkan suatu nilai, karena tidak dapat ditetapkan ulang setelah dibuat, sehingga setiap akan tetap undefined selamanya. Jika Anda mencoba mendeklarasikan konstanta tanpa menginisialisasinya, Anda mendapatkan {i>syntax<i}:

const myConstant;
Uncaught SyntaxError: missing = in const declaration

Mencoba mengubah nilai variabel yang dideklarasikan dengan const seperti yang mungkin mengubah nilai variabel yang dideklarasikan dengan let (atau var) menyebabkan jenis {i>error<i}:

const myConstant = true;

myConstant = false;
> Uncaught TypeError: invalid assignment to const 'myConstant'

Akan tetapi, bila konstanta dikaitkan dengan objek, properti objek dapat diubah.

const constantObject = { "firstvalue" : true };

constantObject
> Object { firstvalue: true }

constantObject.secondvalue = false;

constantObject
> Object { firstvalue: true, secondvalue: false }

Konstanta yang berisi objek adalah nilai yang tidak dapat diubah referensi ke nilai data yang dapat berubah. Meskipun konstanta itu sendiri tidak dapat diubah, properti referensi objek dapat diubah, ditambahkan, atau dihapus:

const constantObject = { "firstvalue" : true };

constantObject = false
> Uncaught TypeError: invalid assignment to const 'constantObject'

Jika Anda tidak mengharapkan suatu variabel ditetapkan ulang, praktik terbaiknya adalah suatu konstanta. Dengan menggunakan const, Anda akan memberi tahu tim pengembangan atau pengelola di masa mendatang tentang proyek untuk tidak mengubah nilai tersebut, agar tidak merusak asumsi kode Anda bagaimana penggunaannya—misalnya, suatu variabel pada akhirnya akan dievaluasi berdasarkan tipe data yang diharapkan.

Cakupan variabel

Cakupan variabel adalah bagian dari skrip tempat variabel tersebut tersedia. Di luar cakupan variabel, variabel tersebut tidak akan ditentukan—bukan sebagai ID berisi nilai undefined, tetapi seolah-olah belum dideklarasikan.

Bergantung pada kata kunci yang Anda gunakan untuk mendeklarasikan variabel dan konteks tempat Anda menentukannya, Anda dapat menentukan cakupan variabel untuk memblokir pernyataan (memblokir cakupan), fungsi individual (cakupan fungsi), atau seluruh aplikasi JavaScript (cakupan global).

Blokir cakupan

Variabel apa pun yang Anda deklarasikan menggunakan let atau const diberi cakupan ke terdekat yang berisi pernyataan blok, artinya variabel hanya dapat diakses dalam blok tersebut. Mencoba untuk mengakses variabel cakupan blok di luar blok penampungnya akan menyebabkan kesalahan saat mencoba mengakses variabel yang tidak ada:

{
    let scopedVariable = true;
    console.log( scopedVariable );
}
> true

scopedVariable
> ReferenceError: scopedVariable is not defined

Terkait JavaScript, variabel cakupan blok tidak ada luar blok yang di dalamnya. Misalnya, Anda dapat mendeklarasikan konstanta di dalam blok, dan kemudian mendeklarasikan konstanta lain di luar blok yang menggunakan pengenal yang sama:

{
  const myConstant = false;
}
const myConstant = true;

scopedConstant;
> true

Meskipun variabel yang dideklarasikan tidak dapat diperluas ke blok induknya, variabel tersebut adalah tersedia untuk semua blok turunan:

{
    let scopedVariable = true;
    {
    console.log( scopedVariable );
    }
}
> true

Nilai variabel yang dideklarasikan dapat diubah dari dalam blok turunan:

{
    let scopedVariable = false;
    {
    scopedVariable = true;
    }
    console.log( scopedVariable );
}
> true

Variabel baru dapat diinisialisasi dengan let atau const di dalam turunan memblokir tanpa error, meskipun menggunakan ID yang sama dengan variabel dalam blok induk:

{
    let scopedVariable = false;
    {
    let scopedVariable = true;
    }
    console.log( scopedVariable );
}
> false

Cakupan Fungsi

Variabel yang dideklarasikan menggunakan var tercakup ke fungsi penampung terdekatnya (atau blok inisialisasi statis di dalam class).

function myFunction() {
    var scopedVariable = true;

    return scopedVariable;
}

scopedVariable;
> ReferenceError: scopedVariable is not defined

Ini masih terjadi setelah fungsi dipanggil. Meskipun variabel diinisialisasi saat fungsi dieksekusi, variabel tersebut masih tidak tersedia di luar cakupan fungsi:

function myFunction() {
    var scopedVariable = true;

    return scopedVariable;
}

scopedVariable;
> ReferenceError: scopedVariable is not defined

myFunction();
> true

scopedVariable;
> ReferenceError: scopedVariable is not defined

Cakupan global

Variabel global tersedia di seluruh aplikasi JavaScript, di dalam setiap dan semua blok dan fungsi, ke skrip apa pun di halaman.

Meskipun ini tampak seperti {i>default<i} yang diinginkan, variabel yang dapat diakses dan dimodifikasi, dapat menambah beban yang tidak perlu, atau bahkan menyebabkan tabrakan dengan variabel di tempat lain dalam aplikasi dengan ID yang sama. Ini berlaku untuk setiap dan semua JavaScript yang terlibat dalam rendering halaman, termasuk hal-hal seperti perpustakaan pihak ketiga dan analisis pengguna. Oleh karena itu, praktik terbaik untuk menghindari polusi pada cakupan global jika memungkinkan.

Variabel apa pun yang dideklarasikan menggunakan var di luar fungsi induk, atau menggunakan let atau const di luar blok induk, bersifat global:

var functionGlobal = true; // Global
let blockGlobal = true; // Global

{
    console.log( blockGlobal );
    console.log( functionGlobal );
}
> true
> true

(function() {
    console.log( blockGlobal );
    console.log( functionGlobal );
}());
> true
> true

Menetapkan nilai ke suatu variabel tanpa mendeklarasikannya secara eksplisit (yaitu, dengan tanpa pernah menggunakan var, let, atau const untuk membuatnya) mengangkat variabel ke global, bahkan ketika diinisialisasi di dalam fungsi atau blok. Sebuah variabel yang dibuat menggunakan pola ini kadang-kadang disebut “global implisit”.

function myFunction() {
    globalVariable = "global";

    return globalVariable
}

myFunction()\
> "global"

globalVariable\
> "global"

Pengangkatan Variabel

Variabel dan deklarasi fungsi diangkat ke bagian atas cakupannya, artinya penerjemah JavaScript memproses variabel yang dideklarasikan pada dalam naskah dan secara efektif memindahkannya ke baris pertama cakupan sebelum mengeksekusi skrip. Ini berarti bahwa variabel yang dideklarasikan menggunakan var dapat direferensikan sebelum variabel dideklarasikan tanpa menemui parameter {i>error<i}:

hoistedVariable
> undefined

var hoistedVariable;

Karena hanya deklarasi variabel yang di-{i>host<i}, bukan inisialisasi, variabel yang belum dideklarasikan secara eksplisit dengan var, let, atau const tidak diangkat:

unhoistedVariable;
> Uncaught ReferenceError: unhoistedVariable is not defined

unhoistedVariable = true;

Seperti yang disebutkan sebelumnya, variabel yang dideklarasikan tetapi tidak diinisialisasi diberi nilai undefined. Perilaku tersebut berlaku untuk variabel yang diangkat deklarasi, tetapi hanya untuk deklarasi yang dideklarasikan menggunakan var.

hoistedVariable
> undefined

var hoistedVariable = 2 + 2;

hoistedVariable\
> 4

Perilaku yang tidak intuitif ini merupakan kelanjutan dari keputusan desain yang dibuat di versi paling awal dari JavaScript, dan tidak dapat diubah tanpa risiko merusak situs yang ada.

let dan const mengatasi perilaku ini dengan menampilkan error saat diakses sebelum dibuat:

{
    hoistedVariable;

    let hoistedVariable;
}
> Uncaught ReferenceError: can't access lexical declaration 'hoistedVariable' before initialization

Error ini berbeda dengan "hoistedVariable is not Define" error lo saat mencoba mengakses variabel yang tidak dideklarasikan. Karena JavaScript telah mengangkat variabel, diketahui bahwa variabel akan dibuat di dalam ruang lingkup yang ditentukan. Namun, alih-alih menyediakan variabel tersebut sebelum dengan nilai undefined, penafsir akan menampilkan error. Variabel yang dideklarasikan dengan let atau const (atau class) dikatakan ada di "zona mati sementara" ("TDZ") dari awal blok pembatasnya hingga titik di kode tempat variabel dideklarasikan.

Zona mati temporal membuat perilaku let lebih intuitif daripada var untuk penulis. Hal ini juga penting untuk desain const. Karena konstanta tidak dapat digunakan diubah, konstanta diangkat ke bagian atas cakupannya dan diberi nilai implisit dari undefined tidak dapat diinisialisasi dengan nilai yang bermakna.

Menguji pemahaman Anda

Jenis karakter apa yang dapat Anda gunakan untuk memulai ID?

Digit
Huruf
Garis bawah

Manakah metode yang lebih disukai untuk mendeklarasikan variabel yang nilainya dapat diubah kapan saja?

var
biarkan
const