@thefourtheye benar dalam mengatakan bahwa variabel-variabel ini tidak dapat diakses sebelum dideklarasikan. Namun, ini sedikit lebih rumit dari itu.
Apakah variabel dideklarasikan dengan let
atau const
tidak diangkat? Apa yang sebenarnya terjadi di sini?
Semua deklarasi ( var
, let
, const
, function
, function*
, class
) yang "mengangkat" dalam JavaScript. Ini berarti bahwa jika nama dideklarasikan dalam lingkup, dalam lingkup itu pengidentifikasi akan selalu referensi variabel tertentu:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Ini berlaku untuk fungsi dan blok cakupan 1 .
Perbedaan antara var
/ function
/ function*
deklarasi dan let
/ const
/ class
deklarasi adalah inisialisasi .
Yang pertama diinisialisasi dengan undefined
atau fungsi (generator) tepat ketika mengikat dibuat di bagian atas ruang lingkup. Namun variabel yang dinyatakan secara leksikal tetap tidak diinisialisasi . Ini berarti bahwa ReferenceError
pengecualian dilemparkan ketika Anda mencoba mengaksesnya. Ini hanya akan diinisialisasi ketika pernyataan let
/ const
/ class
dievaluasi, semuanya sebelum (di atas) yang disebut zona mati sementara .
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Perhatikan bahwa let y;
pernyataan akan menginisialisasi variabel dengan undefined
like let y = undefined;
.
The sementara zona mati bukanlah lokasi sintaksis, melainkan waktu antara variabel (lingkup) penciptaan dan inisialisasi. Itu bukan kesalahan untuk referensi variabel dalam kode di atas pernyataan selama kode itu tidak dieksekusi (misalnya fungsi tubuh atau kode mati), dan itu akan membuang pengecualian jika Anda mengakses variabel sebelum inisialisasi bahkan jika mengakses kode di bawah deklarasi (mis. dalam deklarasi fungsi yang diangkat yang disebut terlalu dini).
Apakah ada perbedaan antara let
dan const
dalam hal ini?
Tidak, mereka bekerja sama sejauh mengangkat dianggap. Satu-satunya perbedaan di antara mereka adalah bahwa const
semut harus dan hanya dapat ditugaskan di bagian initialiser dari deklarasi ( const one = 1;
, baik const one;
dan kemudian penugasan kembali seperti one = 2
tidak valid).
1: var
deklarasi masih bekerja hanya pada level fungsi, tentu saja
let foo = () => bar; let bar = 'bar'; foo();
menggambarkan semua deklarasi adalah efek mengangkat lebih baik, karena tidak jelas karena zona mati sementara.const
sukalet
adalah cacat desain. Dalam ruang lingkup,const
seharusnya dibuat untuk diangkat dan tepat waktu diinisialisasi ketika diakses. Sungguh, mereka harus memiliki kata kunci aconst
, alet
, dan lainnya yang menciptakan variabel yang berfungsi seperti "hanya baca"let
.Mengutip bagian spesifikasi
let
danconst
deklarasi ECMAScript 6 (ECMAScript 2015) ,Jadi, untuk menjawab pertanyaan Anda, ya,
let
danconst
angkat tetapi Anda tidak dapat mengaksesnya sebelum deklarasi aktual dievaluasi saat runtime.sumber
ES6
memperkenalkanLet
variabel yang muncul denganblock level scoping
. SampaiES5
kita tidak punyablock level scoping
, jadi variabel yang dideklarasikan di dalam blok selaluhoisted
berfungsi scoping level.Pada dasarnya
Scope
merujuk ke mana dalam program Anda variabel Anda terlihat, yang menentukan di mana Anda diizinkan untuk menggunakan variabel yang telah Anda nyatakan. DiES5
kita milikiglobal scope,function scope and try/catch scope
, denganES6
kita juga mendapatkan pelingkupan tingkat blok dengan menggunakan Let.var
kata kunci, itu diketahui seluruh fungsi dari saat itu didefinisikan.Ketika Anda mendefinisikan variabel dengan
let
pernyataan itu hanya diketahui di blok itu didefinisikan.Jika Anda menjalankan kode, Anda bisa melihat variabel
j
hanya dikenal diloop
dan bukan sebelum dan sesudah. Namun, variabel kamii
dikenalentire function
sejak saat itu didefinisikan seterusnya.Ada keuntungan besar lainnya menggunakan let karena menciptakan lingkungan leksikal baru dan juga mengikat nilai segar daripada mempertahankan referensi lama.
for
Loop pertama selalu mencetak nilai terakhir , denganlet
itu menciptakan ruang lingkup baru dan mengikat nilai baru mencetak kita1, 2, 3, 4, 5
.Datang ke
constants
, itu bekerja pada dasarnya sepertilet
, satu-satunya perbedaan adalah nilainya tidak dapat diubah. Dalam konstanta mutasi diperbolehkan tetapi pengalihan tugas tidak diizinkan.Jika sebuah konstanta merujuk pada
object
, ia akan selalu merujuk keobject
tetapi konstantaobject
itu sendiri dapat diubah (jika bisa berubah). Jika Anda ingin memiliki yang kekalobject
, Anda bisa menggunakannyaObject.freeze([])
sumber
Dari dokumen web MDN:
Dalam ECMAScript 2015,
let
danconst
diangkat tetapi tidak diinisialisasi. Merujuk variabel di blok sebelum deklarasi variabel menghasilkan dalamReferenceError
karena variabel berada dalam "zona mati temporal" dari awal blok sampai deklarasi diproses.sumber
di es6 ketika kita menggunakan let atau const kita harus mendeklarasikan variabel sebelum menggunakannya. misalnya. 1 -
misalnya. 2-
sumber