CATATAN : Pertanyaan ini ditanyakan dari sudut pandang ECMAScript versi 3 atau 5. Jawabannya mungkin menjadi usang dengan pengenalan fitur-fitur baru dalam rilis ECMAScript 6.
Apa sebenarnya fungsi var
kata kunci dalam JavaScript, dan apa perbedaannya
var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;
dan
someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;
?
Kapan Anda akan menggunakan salah satunya, dan mengapa / apa fungsinya?
Jawaban:
Jika Anda berada dalam lingkup global maka tidak ada banyak perbedaan. Baca jawaban Kangax untuk penjelasan
Jika Anda berada dalam suatu fungsi maka
var
akan membuat variabel lokal, "no var" akan mencari rantai lingkup sampai menemukan variabel atau mengenai lingkup global (pada titik mana ia akan membuatnya):Jika Anda tidak melakukan tugas maka Anda perlu menggunakan
var
:sumber
Ada perbedaan .
var x = 1
mendeklarasikan variabelx
dalam lingkup saat ini (alias konteks eksekusi). Jika deklarasi muncul dalam suatu fungsi - variabel lokal dideklarasikan; jika itu dalam lingkup global - variabel global dideklarasikan.x = 1
, di sisi lain, hanyalah penugasan properti. Pertama kali mencoba untuk menyelesaikanx
terhadap rantai ruang lingkup. Jika menemukannya di mana saja dalam rantai lingkup itu, ia melakukan tugas; jika tidak ditemukanx
, barulah ia menciptakanx
properti pada objek global (yang merupakan objek tingkat atas dalam rantai lingkup).Sekarang, perhatikan bahwa itu tidak mendeklarasikan variabel global, itu menciptakan properti global.
Perbedaan antara keduanya adalah halus dan mungkin membingungkan kecuali Anda memahami bahwa deklarasi variabel juga membuat properti (hanya pada Objek Variabel) dan bahwa setiap properti di Javascript (yah, ECMAScript) memiliki flag tertentu yang menggambarkan properti mereka - ReadOnly, DontEnum dan DontDelete.
Karena deklarasi variabel membuat properti dengan flag DontDelete, perbedaan antara
var x = 1
danx = 1
(ketika dieksekusi dalam lingkup global) adalah bahwa deklarasi satu - variabel - menciptakan properti DontDelete'able, dan yang terakhir tidak. Sebagai akibatnya, properti yang dibuat melalui penugasan implisit ini kemudian dapat dihapus dari objek global, dan yang pertama - yang dibuat melalui deklarasi variabel - tidak dapat dihapus.Tapi ini hanya teori saja, dan dalam praktiknya ada lebih banyak perbedaan di antara keduanya , karena berbagai bug dalam implementasi (seperti yang dari IE).
Semoga semuanya masuk akal :)
[Pembaruan 2010/12/16]
Dalam ES5 (ECMAScript 5; baru-baru ini distandarisasi, edisi ke-5 bahasa) ada yang disebut "mode ketat" - mode bahasa opt-in, yang sedikit mengubah perilaku tugas yang tidak diumumkan. Dalam mode ketat, penugasan ke pengidentifikasi yang tidak diumumkan adalah ReferenceError . Alasan untuk ini adalah untuk menangkap tugas yang tidak disengaja, mencegah penciptaan properti global yang tidak diinginkan. Beberapa browser yang lebih baru sudah mulai menggulirkan dukungan untuk mode ketat. Lihat, misalnya, tabel compat saya .
sumber
delete
mendeklarasikan variabel var dengan beberapaeval
peretasan. Jika saya ingat trik tepatnya saya akan memposting di sini.var someObject = {}
dansomeObject.someProperty = 5
? AkansomeProperty
menjadi global, sementara objek itu adalah milik tetap lokal?false
) , Anda dapat membaca tentang ini sehubungan denganObject.defineProperty
danObject.getOwnPropertyDescriptor
Mengatakan itu perbedaan antara " lokal dan global " tidak sepenuhnya akurat.
Mungkin lebih baik untuk menganggapnya sebagai perbedaan antara " lokal dan terdekat ". Yang terdekat pasti bisa bersifat global, tetapi itu tidak selalu terjadi.
sumber
outer
tempat Anda mendefinisikanvar global = false;
?var global = local;
dalam hal ini ruang lingkup terdekat dari lokal adalah ruang lingkup luar "lokal" yang secara aktif didefinisikan. Meskipun akan aneh jika Anda akan mengubah baris yang samavar global = global
dalam hal ruang lingkup terdekat saat mencari nilaiglobal
akan naik level di ruang lingkup jendela global.Ketika Javascript dieksekusi di browser, semua kode Anda dikelilingi oleh pernyataan with, seperti:
Info lebih lanjut tentang
with
- MDNKarena
var
mendeklarasikan variabel dalam cakupan saat ini , tidak ada perbedaan antara mendeklarasikanvar
jendela bagian dalam dan tidak mendeklarasikannya sama sekali.Perbedaannya muncul ketika Anda tidak berada langsung di dalam jendela, misalnya di dalam suatu fungsi atau di dalam blok.
Menggunakan
var
memungkinkan Anda menyembunyikan variabel eksternal yang memiliki nama yang sama. Dengan cara ini Anda bisa mensimulasikan variabel "pribadi", tapi itu topik lain.Aturan praktis adalah untuk selalu menggunakan
var
, karena jika tidak Anda berisiko memperkenalkan bug halus.EDIT: Setelah kritik yang saya terima, saya ingin menekankan yang berikut:
var
mendeklarasikan variabel dalam cakupan saat iniwindow
var
secara implisit menyatakanvar
dalam lingkup global (jendela)var
sama dengan menghilangkannya.var
tidak sama dengan mendeklarasikan variabel tanpavar
var
secara eksplisit karena itu praktik yang baiksumber
let
ES6.Selalu gunakan
var
kata kunci untuk mendeklarasikan variabel. Mengapa? Praktik pengkodean yang baik seharusnya cukup menjadi alasan tersendiri, tetapi menghilangkannya berarti dideklarasikan dalam lingkup global (variabel seperti ini disebut global "tersirat"). Douglas Crockford merekomendasikan untuk tidak pernah menggunakan global tersirat , dan menurut Pedoman Pengkodean JavaScript Apple :sumber
good coding practice
selalu alasan yang cukup jika ini merupakan praktik terbaik yang disarankan, yang ini dan oleh beberapa penulis Javascript.Berikut ini adalah contoh yang cukup baik tentang bagaimana Anda bisa tertangkap karena tidak mendeklarasikan variabel lokal dengan
var
:(
i
Di-reset pada setiap iterasi dari loop, karena tidak dinyatakan secara lokal dalamfor
loop tetapi secara global) akhirnya menghasilkan loop tak terbatassumber
Saya akan mengatakan itu lebih baik untuk digunakan
var
dalam kebanyakan situasi.Variabel lokal selalu lebih cepat daripada variabel dalam lingkup global.
Jika Anda tidak menggunakan
var
untuk mendeklarasikan variabel, variabel tersebut akan berada dalam lingkup global.Untuk informasi lebih lanjut, Anda dapat mencari "JavaScript rantai lingkup" di Google.
sumber
Jangan gunakan
var
!var
adalah cara pra-ES6 untuk mendeklarasikan variabel. Kami sekarang di masa depan , dan Anda harus mengkodekannya.Gunakan
const
danlet
const
harus digunakan untuk 95% kasus. Itu membuatnya sehingga referensi variabel tidak dapat berubah, sehingga array, objek, dan properti DOM node dapat berubah dan seharusnyaconst
.let
harus digunakan untuk variabel apa saja yang akan dipindahkan. Ini termasuk dalam for loop. Jika Anda pernah menulis divarName =
luar inisialisasi, gunakanlet
.Keduanya memiliki ruang lingkup tingkat blok, seperti yang diharapkan di sebagian besar bahasa lain.
sumber
perbedaan lain misalnya
sementara
sumber
var
?var a
diangkat ke atas lingkup dan diatur ke nol yang menyatakan tetapi tidak menginisialisasi variabel, maka dalam penugasan Anda memiliki referensi ke variabel nol yang tidak ditentukan yang mengevaluasi ke false, dan mengatur penugasan ke[]
. Dalam yang terakhir, Anda memiliki tugas ke propertia
dari propertia
. Anda dapat menugaskan ke properti yang tidak ada - membuatnya saat penugasan, tetapi Anda tidak dapat membaca dari properti yang tidak ada tanpa harusReferenceError
dilemparkan ke arah Anda.Menggunakan
var
selalu merupakan ide yang baik untuk mencegah variabel mengacaukan ruang lingkup global dan variabel saling bertentangan, menyebabkan penimpaan yang tidak diinginkan.sumber
Tanpa
var
- variabel global.Sangat disarankan untuk SELALU menggunakan
var
pernyataan, karena variabel global init dalam konteks lokal - adalah jahat. Tetapi, jika Anda membutuhkan trik kotor ini, Anda harus menulis komentar di awal halaman:sumber
Ini adalah contoh kode yang saya tulis agar Anda memahami konsep ini:
sumber
@ Chris S memberikan contoh yang bagus menunjukkan perbedaan praktis (dan bahaya) antara
var
dan tidakvar
. Inilah yang lain, saya menemukan ini sangat berbahaya karena perbedaannya hanya terlihat di lingkungan asinkron sehingga dapat dengan mudah lolos selama pengujian.Seperti yang Anda harapkan dari output cuplikan berikut
["text"]
:Begitu juga cuplikan berikut (perhatikan yang hilang
let
sebelumnyaarray
):Menjalankan manipulasi data secara tidak sinkron masih menghasilkan hasil yang sama dengan satu pelaksana:
Tetapi berperilaku berbeda dengan banyak yang:
Namun, gunakan let:
sumber
Ketika seseorang mencoba mempelajari ini, inilah cara saya melihatnya. Contoh-contoh di atas mungkin agak terlalu rumit untuk pemula.
Jika Anda menjalankan kode ini:
Output akan berbunyi: false, false, true, true
Karena ia melihat variabel dalam fungsi sebagai terpisah dari yang di luarnya, maka istilah variabel lokal dan ini adalah karena kami menggunakan var dalam penugasan. Jika Anda mengambil var di fungsi jadi sekarang berbunyi seperti ini:
Outputnya salah, salah, salah, salah
Ini karena alih-alih membuat variabel baru dalam lingkup atau fungsi lokal, ia hanya menggunakan variabel global dan menugaskannya menjadi false.
sumber
Saya melihat orang-orang bingung ketika mendeklarasikan variabel dengan atau tanpa var dan di dalam atau di luar fungsi. Berikut adalah contoh mendalam yang akan memandu Anda melalui langkah-langkah ini:
Lihat skrip di bawah ini dalam aksi di sini di jsfiddle
sumber
Di dalam kode Anda jika Anda menggunakan variabel tanpa menggunakan var, maka yang terjadi adalah var_name secara otomatis ditempatkan di lingkup global misalnya:
sumber
Selain masalah cakupan, beberapa orang juga menyebutkan mengangkat , tetapi tidak ada yang memberi contoh. Inilah satu untuk lingkup global:
sumber
Tanpa menggunakan variabel "var" hanya dapat menentukan kapan menetapkan nilai. Sebagai contoh:
tidak dapat bekerja dalam lingkup global atau dalam lingkup lain apa pun . Itu harus dengan nilai seperti:
Di sisi lain, Anda dapat mendefinisikan seperti vaiable;
Nilainya adalah
undefined
(Nilainya tidaknull
dan tidak sama dengan yangnull
menarik.).sumber
my_var;
sebenarnya adalah pernyataan ekspresi yang valid.my_var;
adalah pernyataan ekspresi yang valid ./my_var;
akan menjadi pernyataan yang tidak valid. Tapi seperti yang saya katakan, ini kasuistik tata bahasa, saya minta maaf, komentar saya sebenarnya tidak tepat.Anda harus menggunakan kata kunci var kecuali jika Anda ingin agar variabel dilampirkan ke objek jendela di browser. Berikut ini tautan yang menjelaskan pelingkupan dan perbedaan antara pelingkupan glokal dan pelingkupan lokal dengan dan tanpa kata kunci var.
Ketika variabel didefinisikan tanpa menggunakan kata kunci var, seperti apa itu adalah operasi "penugasan" sederhana.
Ketika nilai ditugaskan ke variabel dalam javascript, penerjemah pertama kali mencoba menemukan "deklarasi variabel" dalam konteks / lingkup yang sama dengan penugasan. Saat penerjemah dieksekusi
dummyVariable = 20
, ia mencari deklarasi dummyVariable di awal fungsi. (Karena semua deklarasi Variabel dipindahkan ke awal konteks oleh penerjemah javascript dan ini disebut hoisting)Anda mungkin juga ingin melihatnya mengangkat dalam javascript
sumber