Apakah ada alasan untuk menggunakan kata kunci "var" di ES6?

261

Panduan Babel untuk ES6 mengatakan:

letadalah yang baru var.

Rupanya satu-satunya perbedaan adalah yang vardicakup untuk fungsi saat ini , sementara letdicakup untuk blok saat ini . Ada beberapa contoh bagus dalam jawaban ini .

Saya tidak dapat melihat alasan untuk menggunakan varkode ES6. Bahkan jika Anda ingin membuat lingkup variabel tertentu ke seluruh fungsi, Anda bisa melakukannya dengan letmeletakkan deklarasi di bagian atas blok fungsi, yang adalah apa yang harus Anda lakukan dengan varmenunjukkan lingkup sebenarnya. Dan jika Anda ingin lingkup sesuatu yang lebih halus di forblok atau sesuatu, maka Anda bisa melakukannya juga.

Jadi insting saya adalah berhenti menggunakan varsama sekali saat menulis kode ES6.

Pertanyaan saya adalah, apakah saya salah tentang ini? Apakah ada kasus yang sah di mana varlebih disukai daripada let?

callum
sumber
3
Saya belum mencoba ini (karena saya belum menulis kode ES6), tetapi tampaknya menggunakan varsebagai indikator sadar bahwa variabel ini dimaksudkan untuk mencakup seluruh fungsi mungkin menjadi konvensi "mendokumentasikan diri" yang berguna .
jfriend00
10
Jika Anda menempatkan letpernyataan tepat di bagian atas fungsi, saya pikir itu sama jelasnya bahwa Anda bermaksud untuk lingkup itu ke seluruh fungsi. Saya tidak berpikir menggunakan varmembuatnya lebih jelas daripada hanya menempatkannya di atas.
callum
11
Jujur, saya percaya bahwa satu-satunya alasan varmasih ada, adalah kompatibilitas ke belakang. Jika bukan karena itu, mereka akan menghapus varsemuanya, atau tidak pernah diperkenalkan letdi tempat pertama, alih-alih mengubah semantik dari varapa yang seharusnya sudah ada sejak lama.
Jörg W Mittag
2
@ RayToal Saya setuju dengan 97% dari apa yang Kyle Simpson katakan, tetapi alasannya untuk tetap menggunakan vartampaknya tipis bagi saya, dan tidak cukup untuk menjamin memiliki jenis variabel ketiga yang melompat-lompat. Anda dapat letmenetapkan cakupan ke seluruh fungsi hanya dengan menempatkannya di bagian atas fungsi, yang maksudnya jauh lebih jelas daripada menulis vardi blok (untuk membuatnya diangkat keluar dari blok itu sehingga Anda dapat menggunakannya di luar blok) - aneh). Dia memperingatkan bahwa jika Anda letmenetapkan suatu fungsi maka "itu hanya posisi yang menandakan perbedaan, daripada sintaksis", tapi saya pikir itu hal yang baik.
callum
2
@ RayToal Saya juga membaca artikel itu (sebelum membaca diskusi ini) dan saya benar-benar kecewa untuk kasusnya yang sangat lemah var. contoh-contoh yang ia tampilkan untuk dijaga vartampaknya dibuat-buat - dan didasarkan pada kesalahan pengkodean yang parah . Jauh lebih baik untuk mengalami kesalahan dan dipaksa untuk memperbaiki kesalahan seperti itu daripada menggunakan fungsi bahasa yang membuat orang bisa melakukannya! Apa selanjutnya, menyarankan untuk membungkus semuanya dalam mencoba / menangkap untuk mencegah crash? Sisa dari tautan itu bagus tapi saya tidak setuju sama sekali dengan bagian tertentu itu.
Mörre

Jawaban:

217

Doug Crockford membahas letpada titik ini dalam ceramahnya, " The Better Parts ".

Intinya adalah, letmenghindari sumber kesalahpahaman, khususnya. untuk programmer dengan harapan yang ditentukan oleh bahasa dengan blok-lingkup A varmemiliki lingkup fungsi (ia menyatakan sebuah variabel yang terlihat di seluruh fungsi) meskipun sepertinya memiliki lingkup blok .

var mungkin masih berguna dalam kasus ekstrem seperti kode yang dihasilkan mesin, tapi saya berusaha keras di sana.

( constjuga baru dan memiliki ruang lingkup blok. Setelah let x = {'hi': 'SE'}Anda dapat menetapkan kembali x, sedangkan setelah const y = xAnda tidak dapat menetapkan ulang y. Itu sering lebih disukai karena itu membuat sesuatu dari sengaja berubah dari bawah Anda. Tetapi untuk menjadi jelas, Anda masih dapat memodifikasi objek y.hi = 'SO'kecuali Anda bekukan.)

Secara realistis, kesan Anda tepat untuk ES6: Adopsi letdan const. Berhenti menggunakan var.

(Dalam kinerja lain "The Better Parts" , Doug mengatakan mengapa ===ditambahkan daripada memperbaiki masalah== . ==Menghasilkan beberapa hasil yang "mengejutkan", jadi adopsi saja ===.)


Contoh Pengungkapan

Jaringan Pengembang Mozilla memberikan contoh di mana vartidak berfungsi sebagaimana dimaksud. Contoh mereka adalah realistis yang menetapkan onclickpenangan di halaman web. Berikut ini adalah test case yang lebih kecil:

var a = [];
(function () {
   'use strict';
   for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
     a.push( function() {return i;} );
   }
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]

// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]

vargagal kami karena semua iterasi loop berbagi ivariabel fungsi-lingkup yang sama , yang memiliki nilai 5setelah loop selesai.

Jerry101
sumber
6
Dia memberikan jawaban yang sama tentang mengadopsi === bukannya ==. Yang terakhir rusak tetapi komite standar ES tidak ingin mengubahnya, jadi mereka menambahkan === Tidak yakin apa artinya itu. ==tidak rusak sama sekali. Ini hanya dapat didefinisikan sebagai equality comparison using coersionPeriksa github.com/getify/Anda-Dont-Know-JS/blob/master/…
AmmarCSE
13
@AmmarCSE itu adalah dokumen 39 halaman yang luar biasa tentang paksaan tersirat. Siapa yang dapat mengingat semua itu saat pemrograman? Doug berarti "rusak" seperti yang dirangkum dalam stackoverflow.com/a/359509/1682419 , singkatnya, mudah untuk mendapatkan bit ketika tipe nilai lebih bervariasi dari yang kita duga. Bisakah Anda memprediksi semua ini? [ '1.0' == 1.0, [1.0] == 1.0, [1.0] == '1.0', ['1.0'] == 1.0, [null] == '', [null] == 'null', '00' == false, [] == [], [] == 0, [] == '', [] == false, [] == true, [010] - [4] == ' 4.0 ', !![0], !![1], [0] == true, [1] == true, 1 == [[1]], 0 == [[0]], '1' == [1] ]
Jerry101
2
benar, sebagian besar contoh tersebut melibatkan operan array. Sangat mudah untuk memahami hasilnya ketika Anda melihat ke toString dan bagaimana penerapannya untuk Objek . Namun, jika itu yang dimaksud dengan broken maka saya benar-benar melihat dari mana datangnya. :-)
AmmarCSE
3
mengapa tidak menggunakan const kapan pun itu tidak bisa berubah - hanya bertanya? Maksudku, pilihan sebenarnya bukan antara letdan varmelainkan antara let, vardanconst
shabunc
4
varberfungsi seperti yang dirancang, tetapi tidak berapa banyak yang diharapkan orang. Ini adalah bug kegunaan, bukan bug implementasi.
Jerry101
12

Jika Anda telah menulis kode yang benar, Anda mungkin dapat mengubah semua varpernyataan menjadi letpernyataan tanpa perubahan semantik.

letlebih disukai karena mengurangi ruang lingkup di mana pengenal terlihat. Hal ini memungkinkan kita untuk mendeklarasikan variabel dengan aman di situs penggunaan pertama.

constlebih disukai daripada let. Kecuali Anda perlu bermutasi referensi, gunakan constdeklarasi. Ini memiliki semua manfaat letseiring dengan mengurangi kehadiran variabel unitial dan membuat kode lebih mudah untuk dipikirkan. Jika Anda tidak yakin apakah Anda perlu bermutasi referensi, menyatakan itu constsampai Anda menemukan diri Anda secara eksplisit perlu melakukannya.

Aluan Haddad
sumber
5

Saya tidak selalu berpikir Anda salah, tetapi ada peringatan untuk menggunakan var. Pada dasarnya, letharus membantu pengembang mengatasi kebodohan JavaScript, terutama dengan konflik penamaan. var, tampaknya, memiliki cakupan yang lebih besar karena ingin pergi ke lingkup fungsi penutup. Akan ada saat ketika Anda membutuhkan var, seperti ketika Anda membutuhkan variabel temp untuk tersedia dalam lingkup blok di dalam fungsi, jika tidak, lebih memilih letvar akan membantu pengembang dengan konflik penamaan. Pada nada yang lebih ringan, sudah saatnya ES6 diperkenalkan let.

penasaran kerjaan
sumber
3
Temp vardi blok tersedia di dalam seluruh fungsi, bukan blok-scoped. Ini adalah fitur yang menyesatkan.
Jerry101
1

Saya cenderung setuju bahwa hanya "biarkan" yang harus digunakan dalam es6. AFIK, mendeklarasikan ulang "let" menghasilkan kesalahan (yang bagus), sementara dengan "var", Anda cukup mengesampingkan nilainya (meskipun "mode ketat" di es5 juga mengurusnya).

yar1
sumber
-4

letberarti "biarkan variabel sama". Ini adalah deklarasi, dengan kata lain, inisialisasi dan penugasan.

Itu ada berbeda dengan constyang tentu saja berarti "konstan" - yang merupakan kebalikan dari variabel.

Beberapa bahasa lain menggunakan awalan ke objek aktual alih-alih objek saat mendeklarasikannya (mis. defAdalah singkatan untuk "define function" - benar-benar kehilangan titik dari apa yang sedang "def".

Let menambahkan inkonsistensi semantik ini ke Javascript.

Secara logis, Anda dapat membiarkan konstanta sama dengan sesuatu juga, karena pekerjaan kata kunci "biarkan" adalah untuk menetapkan memori.

Masalah muncul karena varkata kunci yang diperkenalkan sebelum constdidukung, jadi kompatibilitas mundur menentukan itu vartidak berarti variabel. (Ini juga dapat digunakan untuk menetapkan nilai konstan.)

Oleh karena itu, pengenalan letdi posisi yang salah. Untuk memastikan bahwa kita mengingat bahwa secara leksikal, ini salah, mereka juga memutuskan untuk mengubah ruang lingkup leksikal letvs var, sehingga ketidakkonsistenan adalah yang terpenting dalam pikiran kita ketika melakukan debugging.

Dengan kata lain, letada karena orang (yang berarti pemelihara bahasa) berpikir bahwa Javascript terlalu konsisten, setelah menguasai semua idiom dan idiosinkrasi, menginginkan lebih banyak.

Catatan, vartidak berfungsi di blok "panah" jika Anda ingin memperlakukan blok tersebut sebagai penutupan (karena vardiperkenalkan sebelum memperlakukan blok sebagai penutupan), tetapi berfungsi let.

fijiaaron
sumber
6
-1: bertele-tele, tidak membantu, dan terutama berdasarkan opini.
Joel Mueller
fijiaaron hanya bercanda dengan kita di sini.
Jerry101
Saya bersimpati pada ketidaksukaan Anda terhadap bentuk leksikal letkarena bertentangan dengan nada kata kunci lain dalam kategori yang sama dalam JavaScript. Tetap ini tidak menjawab pertanyaan, dan tidak terlalu baik. Downvoted
Aluan Haddad
3
letbukan hanya pengembang yang menginginkan lebih banyak kerumitan. Ini sebenarnya secara intuitif lebih dimengerti, karena ketika Anda loop-dan-over vars, penutupan mempertahankan nilai terakhir var, tetapi ketika Anda melakukan hal yang sama membiarkan, setiap penutupan dalam loop memiliki nilai sendiri untuk membiarkan, sebuah la contoh oleh @ Jerry101 di atas
TKoL