Lingkup dalam JavaScript selalu menjadi topik yang rumit, terutama bila dibandingkan dengan bahasa yang lebih ketat seperti C dan Java. Selama bertahun-tahun, ruang lingkup JS tidak terlalu banyak dibahas, karena bahasa tersebut tidak memiliki sarana yang secara signifikan akan mempengaruhi situasi saat ini. Tetapi dalam ECMAScript 6 ada beberapa fitur baru yang memungkinkan pengembang untuk lebih mengontrol ruang lingkup variabel. Fitur-fitur ini sekarang sangat didukung oleh browser, mereka cukup dapat diakses oleh sebagian besar pengembang. Namun, kata kunci baru untuk mendeklarasikan variabel, dengan mempertimbangkan fakta bahwa kata kunci
var
lama belum hilang, berarti tidak hanya peluang baru, tetapi juga munculnya pertanyaan baru. Kapan harus menggunakan kata kunci
let
dan
const
? Bagaimana mereka berperilaku? Dalam situasi apa kata kunci
var
masih relevan? Bahan, terjemahan yang kami terbitkan hari ini, bertujuan untuk mengeksplorasi masalah ruang lingkup variabel dalam JavaScript.

Lingkup Variabel: Tinjauan
Ruang lingkup variabel adalah konsep penting dalam pemrograman, yang, bagaimanapun, dapat membingungkan beberapa pengembang, terutama pemula. Lingkup suatu variabel adalah bagian dari program tempat variabel ini dapat diakses.
Lihatlah contoh berikut:
var myVar = 1; function setMyVar() { myVar = 2; } setMyVar(); console.log(myVar);
Apa yang akan dihasilkan oleh metode
console.log
? Jawaban untuk pertanyaan ini tidak akan mengejutkan siapa pun: itu akan menghasilkan
2
. Variabel
myVar
dideklarasikan di luar fungsi, yang memberitahu kita bahwa itu dinyatakan dalam lingkup global. Oleh karena itu, fungsi apa pun yang dideklarasikan dalam cakupan yang sama akan dapat mengakses
myVar
. Bahkan, ketika datang ke kode dieksekusi di browser, bahkan fungsi yang dideklarasikan dalam file lain yang terhubung ke halaman akan memiliki akses ke variabel ini.
Sekarang lihat kode berikut:
function setMyVar() { var myVar = 2; } setMyVar(); console.log(myVar);
Secara lahiriah, perubahannya, dibandingkan dengan contoh sebelumnya, tidak signifikan. Yaitu, kita hanya meletakkan deklarasi variabel di dalam fungsi. Apa yang akan menghasilkan
console.log
sekarang? Pada kenyataannya, tidak ada, karena variabel ini tidak dideklarasikan dan ketika Anda mencoba mengaksesnya, pesan tentang kesalahan
ReferenceError
tidak ditangani akan ditampilkan. Itu terjadi karena variabel dinyatakan di dalam fungsi menggunakan kata kunci
var
. Akibatnya, ruang lingkup variabel ini terbatas pada ruang lingkup fungsi. Dapat diakses di tubuh fungsi ini, fungsi yang tertanam dalam fungsi ini dapat bekerja dengannya, tetapi tidak dapat diakses dari luar. Jika kita memerlukan beberapa fungsi pada level yang sama untuk menggunakan variabel tertentu, kita perlu mendeklarasikan variabel ini di tempat yang sama di mana fungsi-fungsi ini dideklarasikan, yaitu, satu tingkat lebih tinggi dari cakupan internal mereka.
Berikut ini adalah satu pengamatan yang menarik: kode sebagian besar situs web dan aplikasi web tidak berlaku untuk pekerjaan salah satu programmer. Sebagian besar proyek perangkat lunak adalah hasil dari pengembangan tim, dan di samping itu, mereka menggunakan perpustakaan dan kerangka kerja pihak ketiga. Bahkan jika hanya satu programmer yang terlibat dalam pengembangan situs web, ia biasanya menggunakan sumber daya eksternal. Karena itu, biasanya tidak disarankan untuk mendeklarasikan variabel dalam lingkup global, karena Anda tidak dapat mengetahui terlebih dahulu variabel mana yang akan dideklarasikan oleh pengembang lain yang kodenya akan digunakan dalam proyek. Untuk mengatasi masalah ini, beberapa trik dapat digunakan, khususnya, pola "
Modul " dan
IIFE ketika menerapkan pendekatan berorientasi objek untuk pengembangan JavaScript, meskipun enkapsulasi data dan fungsi dalam objek biasa dapat mencapai efek yang sama. Secara umum, dapat dicatat bahwa variabel yang cakupannya melampaui apa yang mereka butuhkan biasanya merupakan masalah yang perlu dilakukan sesuatu.
Masalah kata kunci Var
Jadi, kami menemukan konsep "ruang lingkup". Sekarang mari kita beralih ke hal-hal yang lebih kompleks. Lihatlah kode berikut:
function varTest() { for (var i = 0; i < 3; i++) { console.log(i); } console.log(i); } varTest();
Apa yang akan sampai ke konsol setelah eksekusi? Jelas bahwa nilai-nilai penghitung yang meningkat
i
:
0
,
1
dan
2
akan ditampilkan di dalam loop. Setelah loop berakhir, program terus berjalan. Sekarang kita mencoba mengakses variabel penghitung yang sama yang dideklarasikan dalam
for
loop, di luar loop ini. Apa yang akan terjadi dengan ini?
Setelah memanggil
i
luar loop, 3 akan masuk ke konsol, karena kata kunci
var
bertindak pada tingkat fungsi. Jika Anda mendeklarasikan variabel menggunakan
var
, maka Anda dapat mengaksesnya dalam suatu fungsi bahkan setelah keluar dari konstruksi di mana ia dideklarasikan.
Ini bisa berubah menjadi masalah ketika fungsi menjadi lebih kompleks. Perhatikan contoh berikut:
function doSomething() { var myVar = 1; if (true) { var myVar = 2; console.log(myVar); } console.log(myVar); } doSomething();
Apa yang akan sampai ke konsol sekarang?
2
dan
2
. Kami mendeklarasikan variabel, menginisialisasinya dengan angka 1, dan kemudian mencoba mendefinisikan kembali variabel yang sama di dalam
if
. Karena dua deklarasi ini ada dalam cakupan yang sama, kami tidak dapat mendeklarasikan variabel baru dengan nama yang sama, meskipun kami jelas ingin melakukan hal itu. Akibatnya, variabel pertama ditimpa di dalam
if
.
Ini justru cacat terbesar dari kata kunci
var
. Ruang lingkup variabel yang dinyatakan menggunakannya terlalu besar. Hal ini dapat menyebabkan penulisan ulang data yang tidak disengaja dan kesalahan lainnya. Area visibilitas yang luas sering kali mengarah pada program yang tidak akurat. Secara umum, variabel harus memiliki ruang lingkup yang dibatasi oleh kebutuhannya, tetapi tidak melebihi mereka. Akan menyenangkan untuk dapat mendeklarasikan variabel yang cakupannya tidak sebesar ketika menggunakan
var
, yang akan memungkinkan, jika perlu, untuk menggunakan konstruksi perangkat lunak yang lebih stabil dan lebih baik dari kesalahan. Sebenarnya, ECMAScript 6 memberi kita peluang seperti itu.
Cara-cara baru untuk mendeklarasikan variabel
Standar ECMAScript 6 (serangkaian fitur JavaScript baru, juga dikenal sebagai ES6 dan ES2015) memberi kita dua cara baru untuk mendeklarasikan variabel yang berbeda dalam cakupan, dibandingkan dengan
var
, dan memiliki beberapa fitur lainnya. Ini adalah kata kunci
let
dan
const
. Keduanya memberi kita apa yang disebut ruang lingkup blok. Ini berarti bahwa ruang lingkup penggunaannya dapat dibatasi pada satu blok kode, seperti perulangan
for
atau
if
. Ini memberi pengembang lebih banyak fleksibilitas dalam memilih ruang lingkup variabel. Pertimbangkan kata kunci baru.
▍Gunakan kata kunci let
Kata kunci
let
sangat mirip dengan
var
, perbedaan utamanya adalah lingkup variabel yang dideklarasikan dengannya terbatas. Kami menulis ulang salah satu contoh di atas, menggantikan
var
dengan
let
:
function doSomething() { let myVar = 1; if (true) { let myVar = 2; console.log(myVar); } console.log(myVar); } doSomething();
Dalam hal ini, angka
2
dan
1
akan sampai ke konsol. Ini terjadi karena
if
menetapkan ruang lingkup baru untuk variabel yang dideklarasikan dengan kata kunci
let
. Ini mengarah pada fakta bahwa variabel yang dideklarasikan kedua adalah entitas yang sepenuhnya independen, tidak terkait dengan yang pertama. Anda dapat bekerja dengan mereka secara independen satu sama lain. Namun, ini tidak berarti bahwa blok kode bersarang, seperti
if
kami, benar-benar terputus dari variabel yang dideklarasikan dengan kata kunci
let
dalam lingkup di mana mereka sendiri berada. Lihatlah kode berikut:
function doSomething() { let myVar = 1; if (true) { console.log(myVar); } } doSomething();
Dalam contoh ini, konsol akan mendapatkan nomor
1
. Kode di dalam
if
memiliki akses ke variabel yang kami buat di luarnya. Oleh karena itu, ini menampilkan nilainya di konsol. Dan apa yang terjadi jika Anda mencoba untuk mencampur ruang lingkup? Sebagai contoh, lakukan ini:
function doSomething() { let myVar = 1; if (true) { console.log(myVar); let myVar = 2; console.log(myVar); } } doSomething();
Tampaknya panggilan pertama ke
console.log
akan menghasilkan
1
, tetapi pada kenyataannya, ketika Anda mencoba untuk mengeksekusi kode ini, kesalahan
ReferenceError
akan muncul yang memberi tahu kita bahwa variabel
myVar
untuk lingkup ini tidak ditentukan atau tidak diinisialisasi (teks kesalahan ini berbeda dalam berbagai browser). Dalam JavaScript, ada yang namanya menaikkan variabel ke bagian atas cakupannya. Artinya, jika suatu variabel dideklarasikan dalam lingkup tertentu, JavaScript menyediakan tempat untuk itu bahkan sebelum perintah untuk menyatakannya dijalankan. Bagaimana tepatnya hal ini terjadi berbeda ketika menggunakan
var
dan
let
.
Perhatikan contoh berikut:
console.log(varTest); var varTest = 1; console.log(letTest); let letTest = 2;
Dalam kedua kasus, kami mencoba menggunakan variabel sebelum mendeklarasikannya. Tetapi perintah output konsol berperilaku berbeda. Yang pertama, menggunakan variabel yang nantinya akan dideklarasikan menggunakan kata kunci
var
, akan menghasilkan output yang
undefined
- yaitu, apa yang akan ditulis ke variabel ini. Perintah kedua, yang mencoba mengakses variabel, yang nantinya akan dideklarasikan menggunakan kata kunci
let
, akan melempar
ReferenceError
dan memberi tahu kami bahwa kami mencoba menggunakan variabel sebelum dideklarasikan atau diinisialisasi. Ada apa?
Dan masalahnya di sini adalah bahwa sebelum kode dijalankan, mekanisme yang bertanggung jawab untuk pelaksanaannya melihat kode ini, mencari tahu apakah ada variabel yang akan dideklarasikan di dalamnya, dan, jika demikian, tingkatkan dengan reservasi ruang untuk mereka. Dalam hal ini, variabel yang dideklarasikan menggunakan kata kunci
var
diinisialisasi untuk
undefined
dalam ruang lingkupnya, bahkan jika mereka diakses sebelum dideklarasikan. Masalah utama di sini adalah bahwa nilai yang
undefined
dalam suatu variabel tidak selalu menunjukkan bahwa mereka mencoba menggunakan variabel sebelum deklarasi. Lihatlah contoh berikut:
var var1; console.log(var1); console.log(var2); var var2 = 1;
Dalam hal ini, meskipun
var1
dan
var2
dideklarasikan secara berbeda, kedua panggilan ke
console.log
akan menghasilkan keluaran yang
undefined
. Intinya di sini adalah bahwa dalam variabel yang dideklarasikan dengan
var
, tetapi tidak diinisialisasi, nilai
undefined
secara otomatis ditulis. Pada saat yang sama, seperti yang telah kami katakan, variabel yang dideklarasikan menggunakan
var
, yang diakses sebelum dideklarasikan, juga mengandung
undefined
. Akibatnya, jika terjadi kesalahan dalam kode tersebut, tidak mungkin untuk memahami apa sebenarnya sumber kesalahan - menggunakan variabel yang tidak diinisialisasi atau menggunakan variabel sebelum deklarasi.
Tempat untuk variabel yang dideklarasikan dengan kata kunci
let
dicadangkan di blok mereka, tetapi, sebelum mereka dinyatakan, mereka jatuh ke zona mati sementara (TDZ, Zona Mati Temporal). Ini mengarah pada fakta bahwa mereka tidak dapat digunakan sebelum dideklarasikan, dan upaya untuk mengakses variabel semacam itu mengarah pada kesalahan. Namun, sistem tahu persis penyebab masalahnya dan melaporkannya. Ini terlihat jelas dalam contoh ini:
let var1; console.log(var1); console.log(var2); let var2 = 1;
Di sini, panggilan pertama ke
console.log
akan menampilkan
undefined
, dan yang kedua akan melemparkan kesalahan
ReferenceError
, memberi tahu kami bahwa variabel belum dideklarasikan atau diinisialisasi.
Akibatnya, jika menggunakan
var
tampak
undefined
, kami tidak tahu alasan perilaku program ini. Variabel dapat dideklarasikan dan tidak diinisialisasi, atau mungkin belum dinyatakan dalam lingkup ini, tetapi akan dinyatakan dalam kode yang terletak di bawah perintah untuk mengaksesnya. Dengan menggunakan kata kunci
let
, kita dapat memahami apa yang sebenarnya terjadi, yang jauh lebih berguna untuk debugging.
▍Gunakan kata kunci const
Kata kunci
const
sangat mirip dengan
let
, tetapi mereka memiliki satu perbedaan penting. Kata kunci ini digunakan untuk mendeklarasikan konstanta. Nilai konstanta tidak dapat diubah setelah inisialisasi mereka. Perlu dicatat bahwa ini hanya berlaku untuk nilai tipe primitif, air, string atau angka. Jika konstanta adalah sesuatu yang lebih kompleks, misalnya, sebuah objek atau array, struktur internal dari entitas seperti itu dapat dimodifikasi, Anda tidak bisa hanya menggantinya dengan yang lain. Lihatlah kode berikut:
let mutableVar = 1; const immutableVar = 2; mutableVar = 3; immutableVar = 4;
Kode ini akan dieksekusi hingga baris terakhir. Mencoba untuk menetapkan nilai baru ke konstanta akan menghasilkan kesalahan
TypeError
. Ini adalah bagaimana konstanta berperilaku, tetapi, seperti telah disebutkan, objek yang diinisialisasi oleh konstanta dapat diubah, mereka dapat mengalami mutasi, yang dapat menyebabkan
kejutan .
Mungkin Anda, sebagai pengembang JavaScript, bertanya-tanya mengapa kekebalan variabel penting. Konstanta adalah fenomena baru dalam JavaScript, sementara konstanta adalah bagian penting dari bahasa seperti C atau Java. Mengapa konsep ini begitu populer? Faktanya adalah bahwa menggunakan konstanta membuat kita berpikir tentang cara kerja kode kita. Dalam beberapa situasi, mengubah nilai variabel dapat mengganggu kode, misalnya, jika nomor Pi ditulis di dalamnya dan itu selalu diakses, atau jika variabel memiliki tautan ke elemen HTML yang Anda perlu bekerja dengan terus-menerus. Katakanlah, ini adalah konstanta di mana tautan ke tombol tertentu ditulis:
const myButton = document.querySelector('#my-button');
Jika kode bergantung pada tautan ke elemen HTML, maka kami perlu memastikan keabadian tautan ini. Sebagai hasilnya, kita dapat mengatakan bahwa kata kunci
const
tidak hanya berjalan di sepanjang jalur peningkatan di bidang visibilitas, tetapi juga di sepanjang jalur membatasi kemungkinan memodifikasi nilai-nilai konstanta yang dinyatakan menggunakan kata kunci ini. Ingat bagaimana kita mengatakan bahwa suatu variabel harus memiliki ruang lingkup yang dibutuhkannya. Gagasan ini dapat dilanjutkan dengan mengedepankan rekomendasi, yang menurutnya suatu variabel seharusnya hanya memiliki kemampuan untuk berubah, yang diperlukan untuk pekerjaan yang tepat dengannya, dan tidak lebih.
Berikut ini adalah bahan yang baik tentang topik kekebalan, dari mana kesimpulan penting dapat diambil, yang dengannya penggunaan variabel tidak berubah membuat kita berpikir dengan hati-hati tentang kode kita, yang mengarah pada peningkatan kemurnian kode dan pada pengurangan jumlah kejutan tidak menyenangkan yang muncul selama operasinya.
Ketika saya pertama kali mulai menggunakan kata kunci
let
dan
const
, pada dasarnya saya menggunakan
let
, menggunakan
const
hanya ketika menulis nilai baru ke variabel yang dideklarasikan dengan
let
dapat merusak program. Tapi, belajar lebih banyak tentang pemrograman, saya berubah pikiran tentang hal ini. Sekarang alat utama saya adalah
const
, dan
let
saya menggunakannya hanya ketika nilai variabel perlu ditulis ulang. Ini membuat saya berpikir apakah benar-benar perlu mengubah nilai variabel tertentu. Dalam kebanyakan kasus, ini tidak perlu.
Apakah kita memerlukan kata kunci var?
Kata kunci
let
dan
const
berkontribusi pada pendekatan pemrograman yang lebih bertanggung jawab. Apakah ada situasi di mana kata kunci
var
masih diperlukan? Ya ada. Ada beberapa situasi di mana kata kunci ini masih berguna bagi kami. Pertimbangkan dengan seksama apa yang akan kita bicarakan sebelum mengubah
var
menjadi
let
atau
const
.
▍ Tingkat dukungan kata kunci Var oleh browser
Variabel yang dideklarasikan dengan kata kunci
var
memiliki satu fitur yang sangat penting yang
let
dan kekurangannya. Yaitu, kita berbicara tentang fakta bahwa benar-benar semua browser mendukung kata kunci ini. Meskipun dukungan untuk
let dan
const oleh browser sangat bagus, namun, ada risiko bahwa program Anda akan berakhir di browser yang tidak mendukungnya. Untuk memahami konsekuensi dari insiden semacam itu, Anda perlu mempertimbangkan bagaimana browser menangani kode JavaScript yang tidak didukung, sebagai lawan, misalnya, bagaimana mereka bereaksi terhadap kode CSS yang tidak mereka mengerti.
Jika browser tidak mendukung beberapa fitur CSS, maka ini pada dasarnya mengarah ke beberapa distorsi dari apa yang akan ditampilkan di layar. Situs di peramban yang tidak mendukung gaya apa pun yang digunakan oleh situs tidak akan terlihat seperti yang diharapkan, tetapi kemungkinan besar dapat digunakan. Jika Anda menggunakan, misalnya,
let
, dan browser tidak mendukung kata kunci ini, maka kode JS Anda tidak akan berfungsi di sana. Tidak akan - itu saja. Mengingat bahwa JavaScript adalah salah satu komponen penting dari web modern, ini dapat menjadi masalah serius jika Anda memerlukan program Anda untuk bekerja di browser yang sudah ketinggalan zaman.
Ketika orang berbicara tentang dukungan browser untuk situs, mereka biasanya bertanya di browser mana situs akan bekerja secara optimal. Jika kita berbicara tentang situs yang fungsinya didasarkan pada penggunaan
let
dan
const
, maka pertanyaan serupa harus diajukan secara berbeda: "Di browser mana situs kita tidak akan berfungsi?". Dan ini jauh lebih serius daripada berbicara tentang apakah menggunakan
display: flex
atau tidak. Untuk sebagian besar situs web, jumlah pengguna dengan browser yang usang tidak akan cukup besar untuk dikhawatirkan. Namun, jika kita berbicara tentang sesuatu seperti toko online, atau situs yang pemiliknya membeli iklan, ini bisa menjadi pertimbangan yang sangat penting. Sebelum menggunakan peluang baru dalam proyek semacam itu, nilai tingkat risiko.
Jika Anda perlu mendukung browser yang sangat lama, tetapi Anda ingin menggunakan fitur
let
,
const
, dan ES6 baru lainnya, salah satu solusi untuk masalah ini adalah dengan menggunakan transporter JavaScript seperti
Babel . Transpiler memberikan terjemahan kode baru ke dalam apa yang browser lama akan mengerti. Menggunakan Babel, Anda dapat menulis kode modern yang menggunakan fitur bahasa terbaru, dan kemudian mengubahnya menjadi kode yang dapat dijalankan oleh browser lama.
, ? , . , , , , . , . , , . ES6-, Babel, Babel , , . , , . . ? - IE8 ? , , , , , .
▍ var
,
var
, . . :
var myVar = 1; function myFunction() { var myVar = 2;
,
myVar
, , . , . , , , , . , .
var
.
var myVar = 1; function myFunction() { var myVar = 2; console.log(myVar);
var
,
window
.
let
const
. , JS- , (, , ) , .
, . , . , , , :
let myGlobalVars = {}; let myVar = 1; myGlobalVars.myVar = myVar; function myFunction() { let myVar = 2; console.log(myVar);
, , , , . , ,
var
, , , , , .
Ringkasan
, ? ? :
- IE10 - ? —
var
. - JavaScript, , ,
var
, const
. - (, , ) — let
.
let
const
, ECMAScript 6, ( ) - -. , , , . , - , «» «» , ,
let
const
, .
! ,
const
var
,
let
, , , ?
