Penggunaan const yang tepat untuk mendefinisikan fungsi dalam JavaScript

183

Saya tertarik jika ada batasan untuk jenis nilai apa yang dapat diatur menggunakan constJavaScript — dalam fungsi tertentu. Apakah ini valid? Memang itu berhasil, tetapi apakah itu dianggap praktik buruk karena alasan apa pun?

const doSomething = () => {
   ...
}

Haruskah semua fungsi didefinisikan dengan cara ini di ES6? Sepertinya ini tidak menarik, jika demikian.

Terima kasih atas komentarnya!

David Sinclair
sumber
Anda tampaknya mengajukan beberapa pertanyaan: 1) "Saya tertarik jika ada batasan untuk jenis nilai apa yang dapat ditetapkan menggunakan const dalam JavaScript" No. 2) "Apakah ini valid?" Iya. 3) "apakah itu dianggap praktik buruk karena alasan apa pun" Saya kira belum cukup lama untuk mengatakan sesuatu tentang itu tetapi saya tidak melihat mengapa ini harus menjadi latihan pad. Tidak jauh berbeda dari var doSomething = <function def>;. 4) "Haruskah semua fungsi didefinisikan dengan cara ini di ES6?" Tampaknya merepotkan saya. Saya suka deklarasi fungsi. Semuanya milik mereka sendiri.
Felix Kling
1
Cara saya melihatnya (pendapat, bukan fakta), masuk akal jika Anda ingin melarang mendefinisikan ulang fungsi. Apakah itu waras, atau apakah ada penggunaan fungsional - itu masih bisa diperdebatkan. Jika Anda pikir itu sesuai dengan skenario penggunaan Anda, saya tidak berpikir seseorang dapat memperdebatkan keputusan Anda dan menganggapnya sebagai praktik buruk.
Mjh
4
Saya kira pertanyaannya adalah apa yang ingin Anda capai const. Apakah Anda ingin mencegah diri Anda menimpa fungsi? Saya berasumsi Anda tahu kode Anda untuk tidak melakukan ini. Apakah Anda ingin menyatakan maksudnya doSomething, yaitu bahwa ia memiliki fungsi dan tidak mengubah nilainya? Saya pikir deklarasi fungsi mengkomunikasikan maksud ini dengan jelas juga. Jadi, jika Anda memerlukan "perlindungan runtime" agar tidak menimpa, lakukan saja. Kalau tidak, saya tidak melihat banyak manfaat. Tentu saja jika Anda terutama menggunakan var foo = function() {};, saya akan menggunakan constsebagai gantinya var.
Felix Kling
5
@ Feliksling, "Saya berasumsi Anda tahu kode Anda untuk tidak melakukan ini." - ini argumen yang sangat buruk. Kalau tidak, sama sekali tidak masuk akal const.
Meandre

Jawaban:

253

Tidak ada masalah dengan apa yang telah Anda lakukan, tetapi Anda harus ingat perbedaan antara deklarasi fungsi dan ekspresi fungsi.

Deklarasi fungsi, yaitu:

function doSomething () {}

Diangkat sepenuhnya ke bagian atas ruang lingkup (dan suka letdan constmereka juga dicakup blok).

Ini berarti bahwa yang berikut ini akan berfungsi:

doSomething() // works!
function doSomething() {}

Ekspresi fungsi, yaitu:

[const | let | var] = function () {} (or () =>

Apakah pembuatan fungsi anonim ( function () {}) dan pembuatan variabel, dan kemudian penugasan fungsi anonim tersebut ke variabel itu.

Jadi aturan yang biasa di sekitar variabel mengangkat dalam lingkup - variabel blok-tertutup ( letdan const) tidak mengangkat undefinedke atas lingkup blok mereka.

Ini berarti:

if (true) {
    doSomething() // will fail
    const doSomething = function () {}
}

Akan gagal karena doSomethingtidak ditentukan. (Ini akan melempar ReferenceError)

Jika Anda beralih menggunakan varAnda mendapatkan pengangkat variabel, tetapi akan diinisialisasi undefinedsehingga blok kode di atas masih tidak akan berfungsi. (Ini akan melempar TypeErrorkarena doSomethingbukan fungsi pada saat Anda menyebutnya)

Sejauh praktik standar berjalan, Anda harus selalu menggunakan alat yang tepat untuk pekerjaan itu.

Axel Rauschmayer memiliki pos yang bagus tentang ruang lingkup dan mengangkat termasuk es6 semantik: Variabel dan Pelingkupan dalam ES6

tkone
sumber
7
Hanya ingin menambahkan bahwa kelas es6 menggunakan const secara internal untuk melindungi nama kelas agar tidak dipindahkan di dalam kelas.
user2342460
2
Satu perbedaan halus antara a function a(){console.log(this);} dan b const a=_=>{console.log(this);} adalah jika Anda menyebutnya seperti a.call(someVar);, di a , ia akan mencetak someVar, di b , ia akan mencetak window.
Qian Chen
100

Meskipun menggunakan constuntuk mendefinisikan fungsi tampaknya seperti peretasan, tetapi ia datang dengan beberapa keuntungan besar yang menjadikannya unggul (menurut saya)

  1. Itu membuat fungsi tidak berubah, jadi Anda tidak perlu khawatir tentang fungsi yang diubah oleh beberapa bagian kode lainnya.

  2. Anda dapat menggunakan sintaks panah gemuk, yang lebih pendek & bersih.

  3. Menggunakan fungsi panah menjaga thisikatan untuk Anda.

contoh dengan function

// define a function
function add(x, y) { return x + y; }

// use it
console.log(add(1, 2)); // 3

// oops, someone mutated your function
add = function (x, y) { return x - y; };

// now this is not what you expected
console.log(add(1, 2)); // -1

contoh yang sama dengan const

// define a function (wow! that is 8 chars shorter)
const add = (x, y) => x + y;

// use it
console.log(add(1, 2)); // 3

// someone tries to mutate the function
add = (x, y) => x - y; // Uncaught TypeError: Assignment to constant variable.
// the intruder fails and your function remains unchanged

Gafi
sumber
1
Dan Anda dapat dua kali mendeklarasikan fungsi add (x, y), tetapi Anda tidak dapat mendeklarasikan dua kali const add = ...
TatianaP
33
1. Kekekalan adalah manfaat nyata, tetapi sangat jarang bagi seseorang untuk benar-benar menimpa suatu fungsi. 2. Sintaks panah gemuk tidak lebih pendek kecuali fungsi Anda bisa menjadi ekspresi. function f(x, y) {adalah 18 karakter, const f = (x, y) => {adalah 21 karakter, jadi 3 karakter lebih panjang. 3. Menjaga ikatan ini hanya penting jika fungsi-fungsi didefinisikan di dalam suatu metode (atau fungsi lain yang memiliki makna ini). Pada skrip tingkat atas tidak ada gunanya. Saya tidak mengatakan Anda salah, hanya saja alasan yang Anda sebutkan tidak terlalu relevan.
Nakedible
@Nakedible jadi apa saja alasan sah lainnya?
Anish Ramaswamy
13
Salah satu keuntungan dari sintaks fungsi kuno adalah selama debugging memiliki nama.
user949300
3
Saya akan menggunakan linter untuk mencegah pengikatan kembali deklarasi fungsi.
Franklin Yu
32

Sudah tiga tahun sejak pertanyaan ini diajukan, tetapi saya baru saja menjumpainya. Karena jawaban ini sangat jauh dari tumpukan, perkenankan saya mengulanginya:

T: Saya tertarik jika ada batasan untuk jenis nilai apa yang dapat diatur menggunakan const dalam JavaScript — dalam fungsi tertentu. Apakah ini valid? Memang itu berhasil, tetapi apakah itu dianggap praktik buruk karena alasan apa pun?

Saya termotivasi untuk melakukan penelitian setelah mengamati seorang pembuat kode JavaScript yang produktif yang selalu menggunakan constpernyataan functions, bahkan ketika tidak ada alasan / manfaat yang jelas.

Dalam jawaban untuk " apakah ini dianggap praktik buruk karena alasan apa pun? " Saya katakan, IMO, ya itu, atau setidaknya, ada keuntungan menggunakan functionpernyataan.

Menurut saya ini sebagian besar adalah masalah preferensi dan gaya. Ada beberapa argumen bagus yang disajikan di atas, tetapi tidak ada yang begitu jelas seperti yang dilakukan dalam artikel ini:

Konstan kebingungan: mengapa saya masih menggunakan pernyataan fungsi JavaScript oleh medium.freecodecamp.org/Bill Sourour, guru JavaScript, guru, konsultan, dan guru.

Saya mendorong semua orang untuk membaca artikel itu, bahkan jika Anda sudah membuat keputusan.

Inilah poin-poin utamanya:

Pernyataan fungsi memiliki dua keunggulan yang jelas dibandingkan dengan ekspresi fungsi [const]:

Keuntungan # 1: Kejelasan niat

Saat memindai melalui ribuan baris kode sehari, akan sangat berguna untuk mengetahui maksud programmer secepat dan semudah mungkin.

Keuntungan # 2: Urutan deklarasi == urutan eksekusi

Idealnya, saya ingin mendeklarasikan kode saya kurang lebih dalam urutan yang saya harapkan akan dieksekusi.

Ini adalah showstopper untuk saya: nilai apa pun yang dideklarasikan menggunakan kata kunci const tidak dapat diakses sampai eksekusi mencapainya.

Apa yang baru saja saya jelaskan di atas memaksa kita untuk menulis kode yang terlihat terbalik. Kita harus mulai dengan fungsi level terendah dan terus maju.

Otak saya tidak bekerja seperti itu. Saya ingin konteks sebelum detailnya.

Sebagian besar kode ditulis oleh manusia. Jadi masuk akal bahwa urutan pemahaman kebanyakan orang secara kasar mengikuti urutan eksekusi sebagian besar kode.

JMichaelTX
sumber
1
Bisakah Anda sedikit berkomentar tentang kejelasan niat? Saya mendapatkan # 2, tetapi sejauh yang saya tahu # 1 hanyalah pengulangan (pra?) # 2. Saya dapat memikirkan sebuah kasus, yaitu fungsi yang memiliki defaultErrorHandlerkonstinya sendiri yang ditugaskan sebagai fungsi anonim yang kemudian dapat saya panggil dari penangan janji. Ini akan memungkinkan saya untuk secara opsional 'menimpa' penangan kesalahan default ini dalam fungsi seperti yang saya perlukan. Beberapa hanya perlu mengembalikan objek kesalahan dan yang lain perlu mengembalikan respons http, dengan berbagai tingkat verbositas. Namun struktur kode bisa menjadi pola yang sudah dikenal.
Jake T.
Mungkin ide saya terlalu berbelit-belit! Hanya membungkus kepala saya dengan beberapa praktik baru, belum menghabiskan banyak waktu untuk mengimplementasikannya. Hanya menemukan saya benar-benar menyukai .then( res.success, res.error )lebih dari fungsi anonim yang saya nyatakan hanya menelepon res.success(value);. Memiliki .then( ..., defaultErrorHandler)pola umum bisa menyenangkan, dengan fungsi defaultErrorHandler didefinisikan tingkat atas, dan secara opsional const defaultErrorHandler = error => { ... }mendeklarasikannya dalam lingkup fungsi yang diinginkan.
Jake T.
1
@ JakeT. RE "Bisakah Anda mengomentari sedikit lebih banyak tentang kejelasan niat?". Yah, pertama-tama, pernyataan itu tidak membuat saya, tetapi oleh freecodecamp.org/Bill Sourour, penulis artikel itu. Tapi itu masuk akal bagi saya. Jika saya membaca "fungsi besok ()" maka saya langsung tahu itu adalah fungsi. Tetapi jika saya membaca "const besok = () =>", saya telah berhenti sejenak dan menguraikan sintaks di kepala saya untuk akhirnya menentukan, OK, ya, itu adalah fungsi.
JMichaelTX
1
Hal lain, jika saya memiliki skrip panjang yang ditulis oleh orang lain, dan saya ingin melihat semua fungsi, saya dapat melakukan pencarian cepat pada "fungsi" untuk menemukannya. Atau bahkan lebih baik, saya bisa menulis JS RegEx cepat untuk mengekstrak semua fungsi. IMO, pernyataan "const" hanya untuk data (bukan fungsi) yang TIDAK akan berubah.
JMichaelTX
10

Ada beberapa manfaat yang sangat penting untuk penggunaan const dan beberapa akan mengatakan itu harus digunakan sedapat mungkin karena seberapa disengaja dan indikatif itu.

Sejauh yang saya tahu, itu adalah deklarasi variabel yang paling indikatif dan dapat diprediksi dalam JavaScript, dan salah satu yang paling berguna, KARENA betapa terhambatnya itu. Mengapa? Karena itu menghilangkan beberapa kemungkinan tersedia untuk vardan letdeklarasi.

Apa yang dapat Anda simpulkan saat membaca const? Anda mengetahui semua hal berikut hanya dengan membaca constpernyataan deklarasi, DAN tanpa memindai referensi lain ke variabel itu:

  • nilai terikat ke variabel itu (meskipun objek yang mendasarinya tidak bisa berubah sangat)
  • itu tidak dapat diakses di luar blok yang berisi langsung
  • ikatan tidak pernah diakses sebelum deklarasi, karena aturan Zona Zona Temporal (TDZ).

Kutipan berikut berasal dari artikel yang mengemukakan manfaat letdanconst . Itu juga lebih langsung menjawab pertanyaan Anda tentang batasan / batasan kata kunci:

Kendala seperti yang ditawarkan oleh letdanconst merupakan cara yang kuat untuk membuat kode lebih mudah dipahami. Cobalah untuk menghasilkan sebanyak mungkin kendala ini dalam kode yang Anda tulis. Semakin banyak batasan deklaratif yang membatasi arti sepotong kode, semakin mudah dan cepat bagi manusia untuk membaca, mengurai, dan memahami sepotong kode di masa depan.

Memang, ada lebih banyak aturan untuk constdeklarasi daripada vardeklarasi: blok-lingkup, TDZ, menetapkan pada deklarasi, tidak ada penugasan kembali. Sedangkan varpernyataan hanya fungsi pelingkupan sinyal. Namun, penghitungan aturan tidak menawarkan banyak wawasan. Lebih baik menimbang aturan ini dalam hal kompleksitas: apakah aturan menambah atau mengurangi kompleksitas? Dalam kasus const, pelingkupan blok berarti cakupan yang lebih sempit daripada pelingkupan fungsi, TDZ berarti bahwa kita tidak perlu memindai lingkup mundur dari deklarasi untuk menemukan penggunaan sebelum deklarasi, dan aturan penugasan berarti bahwa penjilidan akan selalu mempertahankan referensi yang sama.

Pernyataan yang lebih terbatas adalah, sepotong kode menjadi lebih sederhana. Saat kami menambahkan batasan pada apa arti pernyataan, kode menjadi lebih tidak terduga. Ini adalah salah satu alasan terbesar mengapa program yang diketik secara statis lebih mudah dibaca daripada yang diketik secara dinamis. Pengetikan statis menempatkan kendala besar pada penulis program, tetapi juga menempatkan kendala besar tentang bagaimana program dapat ditafsirkan, membuat kodenya lebih mudah dimengerti.

Dengan argumen ini dalam pikiran, disarankan agar Anda menggunakan constjika memungkinkan, karena itu adalah pernyataan yang memberi kami kemungkinan paling sedikit untuk dipikirkan.

Sumber: https://ponyfoo.com/articles/var-let-const

mrmaclean89
sumber