Apa ruang lingkup variabel dalam javascript? Apakah mereka memiliki ruang lingkup yang sama di dalam dibandingkan dengan di luar fungsi? Atau apakah itu penting? Juga, di mana variabel disimpan jika mereka didefinisikan secara global?
2013
Jawaban:
TLDR
JavaScript memiliki ruang lingkup dan penutupan leksikal (juga disebut statis). Ini berarti Anda dapat memberi tahu ruang lingkup pengidentifikasi dengan melihat kode sumber.
Keempat lingkup tersebut adalah:
Di luar kasus khusus lingkup global dan modul, variabel dideklarasikan menggunakan
var
(lingkup fungsi),let
(lingkup blok) danconst
(lingkup blok). Sebagian besar bentuk lain dari pernyataan pengidentifikasi memiliki cakupan blok dalam mode ketat.Gambaran
Lingkup adalah wilayah basis kode tempat pengidentifikasi valid.
Lingkungan leksikal adalah pemetaan antara nama pengidentifikasi dan nilai yang terkait dengannya.
Lingkup terbentuk dari sarang yang terhubung dari lingkungan leksikal, dengan setiap tingkat dalam sarang bersesuaian dengan lingkungan leksikal dari konteks eksekusi leluhur.
Lingkungan leksikal yang terhubung ini membentuk "rantai" lingkup. Resolusi pengidentifikasi adalah proses pencarian di sepanjang rantai ini untuk pengidentifikasi yang cocok.
Resolusi pengidentifikasi hanya terjadi dalam satu arah: luar. Dengan cara ini, lingkungan leksikal luar tidak dapat "melihat" ke dalam lingkungan leksikal dalam.
Ada tiga faktor yang bersangkutan dalam memutuskan lingkup dari sebuah identifier dalam JavaScript:
Beberapa cara pengidentifikasi dapat dinyatakan:
var
,let
danconst
var
dalam mode non-ketat)import
pernyataaneval
Beberapa pengidentifikasi lokasi dapat dinyatakan:
Gaya Deklarasi
var
Pengidentifikasi yang dideklarasikan menggunakan
var
lingkup fungsi , terpisah dari ketika mereka dideklarasikan secara langsung dalam konteks global, dalam hal ini mereka ditambahkan sebagai properti pada objek global dan memiliki cakupan global. Ada aturan terpisah untuk penggunaannya dalameval
fungsi.biarkan dan const
Pengidentifikasi dideklarasikan menggunakan
let
danconst
memiliki cakupan blok , selain dari ketika mereka dinyatakan secara langsung dalam konteks global, dalam hal ini mereka memiliki lingkup global.Catatan:
let
,const
danvar
semua mengangkat . Ini berarti bahwa posisi logis dari definisi mereka adalah bagian atas dari ruang lingkup yang dilampirkan (blok atau fungsi). Namun, variabel dinyatakan menggunakanlet
danconst
tidak dapat dibaca atau ditugaskan sampai kontrol telah melewati titik pernyataan dalam kode sumber. Periode sementara dikenal sebagai zona mati temporal.Nama parameter fungsi
Nama parameter fungsi dicakup ke badan fungsi. Perhatikan bahwa ada sedikit kerumitan dalam hal ini. Fungsi yang dideklarasikan sebagai argumen default menutup daftar parameter , dan bukan badan fungsi.
Deklarasi fungsi
Deklarasi fungsi memiliki ruang lingkup blok dalam mode ketat dan ruang lingkup fungsi dalam mode non-ketat. Catatan: mode non-ketat adalah seperangkat aturan yang muncul berdasarkan pada implementasi historis unik dari browser yang berbeda.
Ekspresi fungsi yang dinamai
Ekspresi fungsi yang dinamai dicakup untuk dirinya sendiri (mis. Untuk tujuan rekursi).
Properti yang didefinisikan secara implisit pada objek global
Dalam mode non-ketat, properti yang didefinisikan secara implisit pada objek global memiliki cakupan global, karena objek global berada di bagian atas rantai cakupan. Dalam mode ketat ini tidak diizinkan.
eval
Dalam
eval
string, variabel yang dideklarasikan menggunakanvar
akan ditempatkan dalam lingkup saat ini, atau, jikaeval
digunakan secara tidak langsung, sebagai properti pada objek global.Contohnya
Berikut ini akan melempar ReferenceError karena nama
x
,y
danz
tidak memiliki arti di luar fungsif
.Berikut ini akan melempar ReferenceError untuk
y
danz
, tetapi tidak untukx
, karena visibilitasx
tidak dibatasi oleh blok. Blok yang menentukan tubuh struktur kontrol sepertiif
,for
danwhile
, berperilaku sama.Berikut ini,
x
terlihat di luar loop karenavar
memiliki lingkup fungsi:... karena perilaku ini, Anda harus berhati-hati dalam menutup variabel yang dideklarasikan menggunakan
var
dalam loop. Hanya ada satu instance variabelx
dideklarasikan di sini, dan itu duduk secara logis di luar loop.Cetakan berikut
5
, lima kali, dan kemudian mencetak5
untuk keenam kalinya diconsole.log
luar loop:Cetakan berikut
undefined
karenax
diblok-blok. Callback dijalankan satu per satu secara tidak sinkron. Perilaku baru untuklet
variabel berarti bahwa setiap fungsi anonim ditutup melalui variabel yang berbeda bernamax
(tidak seperti yang akan dilakukan denganvar
), dan bilangan bulat0
melalui4
dicetak.Berikut ini TIDAK akan melempar
ReferenceError
karena visibilitasx
tidak dibatasi oleh blok; Namun, itu akan mencetakundefined
karena variabel belum diinisialisasi (karenaif
pernyataan).Variabel yang dideklarasikan di bagian atas
for
loop menggunakanlet
scoped ke badan loop:Berikut ini akan melempar
ReferenceError
karena visibilitasx
dibatasi oleh blok:Variabel yang dideklarasikan menggunakan
var
,let
atauconst
semuanya dicakup dalam modul:Berikut ini akan mendeklarasikan properti pada objek global, karena variabel yang dideklarasikan menggunakan
var
dalam konteks global, ditambahkan sebagai properti ke objek global:let
danconst
dalam konteks global tidak menambahkan properti ke objek global, tetapi masih memiliki cakupan global:Parameter fungsi dapat dianggap dideklarasikan di badan fungsi:
Parameter blok tangkap dicakup ke badan blok tangkap:
Ekspresi fungsi yang dinamai hanya mencakup ekspresi itu sendiri:
Dalam mode non-ketat, properti yang didefinisikan secara implisit pada objek global memiliki cakupan global. Dalam mode ketat Anda mendapatkan kesalahan.
Dalam mode non-ketat, deklarasi fungsi memiliki cakupan fungsi. Dalam mode ketat mereka memiliki ruang lingkup blok.
Cara kerjanya di bawah tenda
Lingkup didefinisikan sebagai wilayah leksikal kode tempat pengidentifikasi valid.
Dalam JavaScript, setiap fungsi-objek memiliki
[[Environment]]
referensi tersembunyi yang merupakan referensi ke lingkungan leksikal dari konteks eksekusi (stack frame) di mana ia dibuat.Ketika Anda memanggil suatu fungsi,
[[Call]]
metode tersembunyi disebut. Metode ini menciptakan konteks eksekusi baru dan membangun tautan antara konteks eksekusi baru dan lingkungan leksikal dari objek-fungsi. Itu melakukan ini dengan menyalin[[Environment]]
nilai pada objek-fungsi, ke referensi luar bidang pada lingkungan leksikal dari konteks eksekusi baru.Perhatikan bahwa tautan ini antara konteks eksekusi baru dan lingkungan leksikal dari objek fungsi disebut closure .
Jadi, dalam JavaScript, ruang lingkup diimplementasikan melalui lingkungan leksikal yang dihubungkan bersama dalam "rantai" oleh referensi luar. Rantai lingkungan leksikal ini disebut rantai lingkup, dan resolusi pengidentifikasi terjadi dengan mencari rantai untuk pengidentifikasi yang cocok.
Cari tahu lebih lanjut .
sumber
Javascript menggunakan rantai lingkup untuk menetapkan ruang lingkup untuk fungsi yang diberikan. Biasanya ada satu lingkup global, dan setiap fungsi yang didefinisikan memiliki cakupan bersarangnya sendiri. Setiap fungsi yang didefinisikan dalam fungsi lain memiliki cakupan lokal yang terkait dengan fungsi luar. Selalu posisi dalam sumber yang menentukan ruang lingkup.
Elemen dalam rantai lingkup pada dasarnya adalah Peta dengan pointer ke lingkup induknya.
Saat menyelesaikan variabel, javascript dimulai pada cakupan terdalam dan mencari ke luar.
sumber
Variabel yang dinyatakan secara global memiliki cakupan global. Variabel yang dideklarasikan dalam suatu fungsi dibatasi untuk fungsi itu, dan membayangi variabel global dengan nama yang sama.
(Saya yakin ada banyak seluk-beluk yang dapat ditunjukkan oleh programmer JavaScript nyata dalam jawaban lain. Khususnya saya menemukan halaman ini tentang apa sebenarnya
this
artinya setiap saat. Mudah-mudahan tautan yang lebih perkenalan ini cukup untuk membantu Anda memulai. .)sumber
JavaScript sekolah tua
Secara tradisional, JavaScript benar-benar hanya memiliki dua jenis ruang lingkup:
Saya tidak akan menguraikan ini, karena sudah ada banyak jawaban lain yang menjelaskan perbedaannya.
JavaScript modern
The spesifikasi JavaScript terbaru kini juga memungkinkan lingkup ketiga:
Bagaimana cara membuat variabel lingkup blok?
Secara tradisional, Anda membuat variabel Anda seperti ini:
Variabel ruang lingkup blok dibuat seperti ini:
Jadi apa perbedaan antara ruang lingkup fungsional dan ruang lingkup blok?
Untuk memahami perbedaan antara ruang lingkup fungsional dan ruang lingkup blok, pertimbangkan kode berikut:
Di sini, kita dapat melihat bahwa variabel kita
j
hanya dikenal di awal untuk loop, tetapi tidak sebelum dan sesudah. Namun, variabel kamii
dikenal di seluruh fungsi.Juga, pertimbangkan bahwa variabel blok ruang tidak diketahui sebelum mereka dinyatakan karena mereka tidak diangkat. Anda juga tidak diizinkan untuk mendeklarasikan ulang variabel scoping blok yang sama dalam blok yang sama. Hal ini membuat variabel yang dicakup blok lebih rentan kesalahan daripada variabel yang dicakup secara global atau fungsional, yang diangkat dan yang tidak menghasilkan kesalahan jika terjadi deklarasi berganda.
Apakah aman menggunakan variabel lingkup blok hari ini?
Apakah aman digunakan hari ini atau tidak, tergantung pada lingkungan Anda:
Jika Anda menulis kode JavaScript sisi-server ( Node.js ), Anda dapat menggunakan
let
pernyataan dengan aman .Jika Anda menulis kode JavaScript sisi klien dan menggunakan transpiler berbasis browser (seperti Traceur atau babel-standalone ), Anda dapat menggunakan
let
pernyataan itu dengan aman , namun kode Anda kemungkinan tidak optimal sehubungan dengan kinerja.Jika Anda menulis kode JavaScript sisi klien dan menggunakan transpiler berbasis Node (seperti skrip traceur shell atau Babel ), Anda dapat menggunakan
let
pernyataan dengan aman . Dan karena browser Anda hanya akan tahu tentang kode yang diubahnya, kelemahan kinerja harus dibatasi.Jika Anda menulis kode JavaScript sisi klien dan tidak menggunakan transpiler, Anda perlu mempertimbangkan dukungan browser.
Ini adalah beberapa browser yang tidak mendukung
let
sama sekali:Bagaimana cara melacak dukungan browser
Untuk gambaran umum terkini tentang browser yang mendukung
let
pernyataan pada saat Anda membaca jawaban ini, lihat halaman iniCan I Use
.(*) Variabel cakupan global dan fungsional dapat diinisialisasi dan digunakan sebelum mereka dinyatakan karena variabel JavaScript diangkat . Ini berarti bahwa deklarasi selalu jauh di atas cakupan.
sumber
Ini sebuah contoh:
Anda akan ingin menyelidiki penutupan, dan bagaimana menggunakannya untuk membuat anggota pribadi .
sumber
Kuncinya, seperti yang saya mengerti, adalah bahwa Javascript memiliki fungsi tingkat scoping vs ruang lingkup blok C yang lebih umum.
Berikut ini adalah artikel bagus tentang masalah ini.
sumber
Dalam "Javascript 1.7" (ekstensi Mozilla ke Javascript) kita juga dapat mendeklarasikan variabel blok-lingkup dengan
let
pernyataan :sumber
let
.Gagasan pelingkupan dalam JavaScript saat awalnya dirancang oleh Brendan Eich berasal dari bahasa penulisan HyperCard HyperTalk .
Dalam bahasa ini, tampilan dilakukan mirip dengan tumpukan kartu indeks. Ada kartu master yang disebut sebagai latar belakang. Itu transparan dan dapat dilihat sebagai kartu terbawah. Konten apa pun pada kartu dasar ini dibagikan dengan kartu yang diletakkan di atasnya. Setiap kartu yang ditempatkan di atas memiliki kontennya sendiri yang diutamakan daripada kartu sebelumnya, tetapi masih memiliki akses ke kartu sebelumnya jika diinginkan.
Inilah tepatnya bagaimana sistem pelingkupan JavaScript dirancang. Hanya saja namanya berbeda. Kartu-kartu dalam JavaScript dikenal sebagai Execution Contexts ECMA . Masing-masing dari konteks ini mengandung tiga bagian utama. Lingkungan variabel, lingkungan leksikal, dan ikatan ini. Kembali ke referensi kartu, lingkungan leksikal berisi semua konten dari kartu sebelumnya yang lebih rendah di tumpukan. Konteks saat ini adalah di bagian atas tumpukan dan konten yang dinyatakan di sana akan disimpan dalam lingkungan variabel. Lingkungan variabel akan didahulukan dalam kasus penamaan tabrakan.
Ikatan ini akan menunjuk ke objek yang berisi. Kadang-kadang lingkup atau konteks eksekusi berubah tanpa objek yang berubah berubah, seperti dalam fungsi yang dideklarasikan di mana objek yang berisi mungkin
window
atau fungsi konstruktor.Konteks eksekusi ini dibuat setiap kali kontrol waktu ditransfer. Kontrol ditransfer ketika kode mulai dijalankan, dan ini terutama dilakukan dari eksekusi fungsi.
Jadi itulah penjelasan teknisnya. Dalam praktiknya, penting untuk diingat dalam JavaScript
Menerapkan ini ke salah satu contoh sebelumnya (5. "Penutupan") di halaman ini, adalah mungkin untuk mengikuti tumpukan konteks eksekusi. Dalam contoh ini ada tiga konteks dalam tumpukan. Mereka didefinisikan oleh konteks luar, konteks dalam fungsi segera dipanggil oleh var enam, dan konteks dalam fungsi yang dikembalikan di dalam fungsi segera dipanggil var enam.
i ) Konteks luar. Ia memiliki lingkungan variabel dari a = 1
ii ) Konteks IIFE, ia memiliki lingkungan leksikal dari a = 1, tetapi lingkungan variabel dari a = 6 yang diutamakan dalam tumpukan
iii ) Konteks fungsi yang dikembalikan, ia memiliki konteks leksikal lingkungan a = 6 dan itu adalah nilai yang dirujuk dalam peringatan ketika dipanggil.
sumber
1) Ada ruang lingkup global, ruang lingkup fungsi, dan dengan dan lingkup menangkap. Tidak ada lingkup level 'blok' secara umum untuk variabel - pernyataan with dan catch menambahkan nama ke blok mereka.
2) Ruang lingkup disarang oleh fungsi sampai ke lingkup global.
3) Properti diselesaikan dengan melalui rantai prototipe. Pernyataan with membawa nama properti objek ke dalam ruang lingkup leksikal yang didefinisikan oleh blok with.
EDIT: ECMAAScript 6 (Harmony) dispesifikasi untuk mendukung let, dan saya tahu chrome memungkinkan bendera 'harmoni', jadi mungkin itu mendukungnya ..
Biarkan akan menjadi dukungan untuk pelingkupan tingkat blok, tetapi Anda harus menggunakan kata kunci untuk mewujudkannya.
EDIT: Berdasarkan Benjamin yang menunjukkan dengan dan menangkap pernyataan di komentar, saya telah mengedit posting, dan menambahkan lebih banyak. Pernyataan with with dan catch mengenalkan variabel ke dalam bloknya masing-masing, dan itu adalah lingkup blok. Variabel-variabel ini alias sifat-sifat objek yang diteruskan ke dalamnya.
EDIT: Contoh klarifikasi:
test1 dicakup ke dalam dengan blok, tetapi alias a.test1. 'Var test1' menciptakan variabel test1 baru dalam konteks leksikal atas (fungsi, atau global), kecuali itu adalah properti dari a - yang mana itu.
Astaga! Hati-hati menggunakan 'with' - sama seperti var adalah noop jika variabel sudah didefinisikan dalam fungsi, itu juga noop sehubungan dengan nama yang diimpor dari objek! Sedikit mengungkit nama yang sudah didefinisikan akan membuat ini jauh lebih aman. Saya pribadi tidak akan pernah menggunakannya dengan ini.
sumber
with
pernyataan ini merupakan bentuk blok scoping tetapicatch
klausa adalah bentuk jauh lebih umum (Fun Bahkan, v8 alatcatch
denganwith
) - itu cukup banyak satu-satunya bentuk blok scoping di JavaScript itu sendiri (Yaitu, fungsi, global, try / catch , dengan dan turunannya), namun lingkungan host memiliki gagasan pelingkupan yang berbeda - misalnya acara inline di browser dan modul vm NodeJS.Saya menemukan bahwa banyak orang yang baru mengenal JavaScript mengalami kesulitan memahami bahwa pewarisan tersedia secara default dalam bahasa dan lingkup fungsi adalah satu-satunya ruang lingkup, sejauh ini. Saya memberikan ekstensi untuk ahli kecantikan yang saya tulis pada akhir tahun lalu yang disebut JSPretty. Fitur warna lingkup fungsi dalam kode dan selalu mengaitkan warna ke semua variabel yang dinyatakan dalam lingkup itu. Penutupan secara visual ditunjukkan ketika variabel dengan warna dari satu lingkup digunakan dalam lingkup yang berbeda.
Coba fitur di:
Lihat demo di:
Lihat kode di:
Saat ini fitur ini menawarkan dukungan untuk kedalaman 16 fungsi bersarang, tetapi saat ini tidak mewarnai variabel global.
sumber
JavaScript hanya memiliki dua jenis ruang lingkup:
var
kata kunci memiliki cakupan fungsional.Setiap kali suatu fungsi dipanggil, objek lingkup variabel dibuat (dan termasuk dalam rantai lingkup) yang diikuti oleh variabel dalam JavaScript.
Rantai cakupan ->
a
danouter
fungsinya berada di level teratas dalam rantai lingkup.variable scope object
(dan termasuk dalam rantai lingkup) ditambahkan dengan variabelb
di dalamnya.Sekarang ketika sebuah variabel
a
diperlukan, pertama-tama mencari ruang lingkup variabel terdekat dan jika variabel tidak ada di sana daripada pindah ke objek berikutnya dari rantai ruang lingkup variabel. Yang dalam hal ini adalah tingkat jendela.sumber
Hanya untuk menambah jawaban lain, ruang lingkup adalah daftar pencarian dari semua pengidentifikasi yang dideklarasikan (variabel), dan menegakkan seperangkat aturan ketat tentang bagaimana ini dapat diakses oleh kode yang sedang dieksekusi. Pencarian ini mungkin untuk keperluan menugaskan ke variabel, yang merupakan referensi LHS (sisi kiri), atau mungkin untuk tujuan mengambil nilainya, yang merupakan referensi RHS (sisi kanan). Pencarian ini adalah apa yang dilakukan mesin JavaScript secara internal saat kompilasi dan eksekusi kode.
Jadi dari perspektif ini, saya berpikir bahwa sebuah gambar akan membantu yang saya temukan dalam ebook Scopes and Closures oleh Kyle Simpson:
Mengutip dari ebook-nya:
Satu hal yang perlu diperhatikan adalah, "Lingkup pencarian berhenti begitu menemukan kecocokan pertama".
Gagasan "tingkat cakupan" ini menjelaskan mengapa "ini" dapat diubah dengan ruang lingkup yang baru dibuat, jika dilihat dalam fungsi bersarang. Berikut adalah tautan yang mencakup semua detail ini, Semua yang Anda ingin tahu tentang cakupan javascript
sumber
jalankan kodenya. berharap ini akan memberi gambaran tentang pelingkupan
sumber
Lingkup Global:
Variabel global persis seperti bintang global (Jackie Chan, Nelson Mandela). Anda dapat mengaksesnya (mendapatkan atau mengatur nilai), dari bagian mana pun dari aplikasi Anda. Fungsi global seperti acara global (Tahun Baru, Natal). Anda dapat mengeksekusi (memanggil) mereka dari bagian mana pun dari aplikasi Anda.
Lingkup Lokal:
Jika Anda berada di AS, Anda mungkin mengenal Kim Kardashian, selebritas terkenal (entah bagaimana ia berhasil membuat tabloid). Tetapi orang-orang di luar AS tidak akan mengenalinya. Dia adalah bintang lokal, terikat ke wilayahnya.
Variabel lokal seperti bintang lokal. Anda hanya dapat mengaksesnya (mendapatkan atau mengatur nilai) di dalam ruang lingkup. Fungsi lokal seperti acara lokal - Anda hanya dapat mengeksekusi (merayakan) di dalam lingkup itu. Jika Anda ingin mengaksesnya dari luar ruang lingkup, Anda akan mendapatkan kesalahan referensi
Periksa artikel ini untuk pemahaman mendalam tentang ruang lingkup
sumber
Hanya ada hampir dua jenis cakupan JavaScript:
Jadi, setiap blok selain fungsi tidak membuat ruang lingkup baru. Itu menjelaskan mengapa for-loop menimpa variabel cakupan luar:
Sebagai gantinya menggunakan fungsi:
Dalam contoh pertama, tidak ada ruang lingkup blok, jadi variabel yang dideklarasikan awalnya ditimpa. Dalam contoh kedua, ada ruang lingkup baru karena fungsi, sehingga variabel yang awalnya dideklarasikan dibagikan, dan tidak ditimpa.
Itu hampir semua yang perlu Anda ketahui dalam hal pelingkupan JavaScript, kecuali:
Jadi Anda dapat melihat pelingkupan JavaScript sebenarnya sangat sederhana, meskipun tidak selalu intuitif. Beberapa hal yang harus diperhatikan:
Jadi kode ini:
setara dengan:
Ini mungkin tampak berlawanan dengan intuisi, tetapi masuk akal dari perspektif perancang bahasa yang sangat penting.
sumber
Js Modern, ES6 +, '
const
' dan 'let
'Anda harus menggunakan scoping blok untuk setiap variabel yang Anda buat, seperti kebanyakan bahasa utama lainnya.
var
sudah usang . Ini membuat kode Anda lebih aman dan lebih dapat dikelola.const
harus digunakan untuk 95% kasus . Itu membuatnya sehingga referensi variabel tidak dapat berubah. Array, objek, dan properti DOM node dapat berubah dan seharusnya terjadiconst
.let
harus digunakan untuk variabel apa saja yang akan dipindahkan. Ini termasuk dalam for loop. Jika Anda pernah mengubah nilai di luar inisialisasi, gunakanlet
.Cakupan blok berarti bahwa variabel hanya akan tersedia dalam tanda kurung di mana ia dinyatakan. Ini meluas ke lingkup internal, termasuk fungsi anonim yang dibuat dalam ruang lingkup Anda.
sumber
Coba contoh menarik ini. Dalam contoh di bawah ini jika a adalah numerik yang diinisialisasi pada 0, Anda akan melihat 0 dan kemudian 1. Kecuali a adalah objek dan javascript akan memberikan f1 sebuah pointer dari bukan salinannya. Hasilnya adalah Anda mendapatkan peringatan yang sama di kedua kali.
sumber
Hanya ada lingkup fungsi di JS. Tidak memblokir cakupan! Anda dapat melihat apa yang mengangkat juga.
sumber
Pemahaman saya adalah bahwa ada 3 lingkup: ruang lingkup global, tersedia secara global; cakupan lokal, tersedia untuk seluruh fungsi terlepas dari blok; dan ruang lingkup blok, hanya tersedia untuk blok, pernyataan, atau ekspresi yang digunakan. Ruang lingkup global dan lokal ditunjukkan dengan kata kunci 'var', baik di dalam fungsi atau di luar, dan ruang lingkup blok ditunjukkan dengan kata kunci 'let'.
Bagi mereka yang percaya hanya ada lingkup global dan lokal, tolong jelaskan mengapa Mozilla akan memiliki seluruh halaman yang menggambarkan nuansa ruang lingkup blok di JS.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
sumber
Masalah yang sangat umum belum dijelaskan bahwa front-end coders sering mengalami adalah ruang lingkup yang terlihat oleh pengendali event inline dalam HTML - misalnya, dengan
Cakupan variabel yang
on*
dapat dirujuk oleh atribut harus :querySelector
sebagai variabel mandiri akan mengarah kedocument.querySelector
; jarang)Kalau tidak, Anda akan mendapatkan ReferenceError ketika pawang dipanggil. Jadi, misalnya, jika inline handler mereferensikan fungsi yang didefinisikan di dalam
window.onload
atau$(function() {
, referensi akan gagal, karena inline handler hanya boleh mereferensikan variabel dalam lingkup global, dan fungsinya bukan global:Tampilkan cuplikan kode
Properti dari
document
dan properti dari elemen handler dilampirkan juga dapat dirujuk sebagai variabel mandiri di dalam handler inline karena handler inline dipanggil dalam duawith
blok , satu untukdocument
, satu untuk elemen. Rantai lingkup variabel di dalam penangan ini sangat tidak intuitif , dan penangan acara kerja mungkin akan memerlukan fungsi untuk menjadi global (dan polusi global yang tidak perlu mungkin harus dihindari ).Karena rantai ruang lingkup di dalam penangan inline sangat aneh , dan karena penangan inline membutuhkan polusi global untuk bekerja, dan karena penangan inline kadang-kadang membutuhkan tali yang jelek keluar ketika melewati argumen, mungkin lebih mudah untuk menghindari mereka. Alih-alih, lampirkan penangan acara menggunakan Javascript (seperti dengan
addEventListener
), bukan dengan markup HTML.Tampilkan cuplikan kode
Pada catatan yang berbeda, tidak seperti
<script>
tag normal , yang berjalan di tingkat atas, kode di dalam modul ES6 berjalan dalam cakupan privasinya sendiri. Variabel yang ditentukan di bagian atas<script>
tag normal adalah global, sehingga Anda dapat merujuknya ke<script>
tag lain , seperti ini:Tampilkan cuplikan kode
Tetapi level teratas dari modul ES6 tidak bersifat global. Variabel yang dideklarasikan di bagian atas modul ES6 hanya akan terlihat di dalam modul itu, kecuali jika variabel tersebut secara eksplisit
export
diedit, atau kecuali jika itu ditugaskan ke properti objek global.Tampilkan cuplikan kode
Tingkat atas modul ES6 mirip dengan bagian dalam IIFE pada tingkat atas secara normal
<script>
. Modul ini dapat merujuk variabel apa pun yang bersifat global, dan tidak ada yang dapat merujuk apa pun di dalam modul kecuali modul tersebut dirancang secara eksplisit untuknya.sumber
Dalam JavaScript ada dua jenis ruang lingkup:
Fungsi di bawah ini memiliki variabel cakupan lokal
carName
. Dan variabel ini tidak dapat diakses dari luar fungsi.Kelas Di Bawah ini memiliki variabel lingkup Global
carName
. Dan variabel ini dapat diakses dari mana saja di kelas.sumber
ES5
dan sebelumnya:Variabel dalam Javascript pada awalnya (pra
ES6
) secara fungsi scoped. Istilah yang dicakup secara leksikal berarti bahwa Anda dapat melihat ruang lingkup variabel dengan 'melihat' kode.Setiap variabel yang dideklarasikan dengan
var
kata kunci dicakup dalam fungsi. Namun, jika fungsi lain dideklarasikan di dalam fungsi itu fungsi-fungsi tersebut akan memiliki akses ke variabel fungsi luar. Ini disebut rantai lingkup . Ini bekerja dengan cara berikut:Contoh:
Apa yang terjadi ketika kita mencoba untuk log variabel
foo
,bar
danfoobar
ke konsol adalah sebagai berikut:innerFunc
itu sendiri. Oleh karena itu, nilai foo diselesaikan ke stringinnerFunc
.innerFunc
itu sendiri. Karena itu, kita perlu mendaki rantai ruang lingkup . Pertama-tama kita melihat fungsi luar di mana fungsiinnerFunc
itu didefinisikan. Ini fungsinyaouterFunc
. Dalam lingkupouterFunc
kita dapat menemukan bar variabel, yang menampung string 'outerFunc'.ES6
(ES 2015) dan lebih lama:Konsep lingkup leksikal dan scopechain yang sama masih berlaku di
ES6
. Namun cara baru untuk mendeklarasikan variabel diperkenalkan. Ada yang berikut ini:let
: membuat variabel blok cakupanconst
: membuat variabel scoped blok yang harus diinisialisasi dan tidak dapat dipindahkanPerbedaan terbesar antara
var
danlet
/const
adalah bahwavar
adalah fungsi scoped sedangkanlet
/const
adalah blok scoped. Berikut adalah contoh untuk menggambarkan ini:Dalam contoh di atas letVar mencatat nilai global karena variabel yang dideklarasikan dengan
let
adalah blok scoped. Mereka tidak ada di luar blok masing-masing, sehingga variabel tidak dapat diakses di luar blok if.sumber
Dalam EcmaScript5, terutama ada dua cakupan, cakupan lokal dan cakupan global, tetapi di EcmaScript6 kami memiliki tiga cakupan, cakupan lokal, cakupan global, dan cakupan baru yang disebut lingkup blok .
Contoh lingkup blok adalah: -
sumber
ECMAScript 6 memperkenalkan kata kunci let dan const. Kata kunci ini dapat digunakan sebagai pengganti kata kunci var. Bertentangan dengan kata kunci var, kata kunci let dan const mendukung deklarasi cakupan lokal di dalam pernyataan blokir.
sumber
Saya sangat suka jawaban yang diterima tetapi saya ingin menambahkan ini:
Lingkup mengumpulkan dan memelihara daftar pencarian dari semua pengidentifikasi yang dideklarasikan (variabel), dan menegakkan seperangkat aturan yang ketat tentang bagaimana ini dapat diakses oleh kode yang sedang dieksekusi.
Lingkup adalah seperangkat aturan untuk mencari variabel dengan nama pengenal mereka.
sumber
Ada dua jenis cakupan dalam JavaScript.
Ruang lingkup global : variabel yang diumumkan dalam ruang lingkup global dapat digunakan di mana saja dalam program dengan sangat lancar. Sebagai contoh:
Cakupan fungsional atau Cakupan lokal : variabel yang dideklarasikan dalam lingkup ini hanya dapat digunakan dalam fungsinya sendiri. Sebagai contoh:
sumber