Mengapa menggunakan `const foo = () => {}` bukan `function foo () {}`

12

Misalnya, dalam video Redux ini , instruktur selalu menggunakan sintaks seperti

const counter = (state=0, action) => {
   ... function body here
}

di mana saya hanya akan menggunakan "tradisional"

function counter(state=0, action) {
   ... function body here
}

Yang sebenarnya lebih pendek dan, IMO, lebih jelas. Lebih mudah untuk memindai tepi kiri halaman yang cukup rata dan terstruktur untuk kata "fungsi" daripada memindai tepi kanan yang acak untuk "">> kecil.

Selain dari this, dan mencoba untuk bersikap objektif, bukan opini, adakah perbedaan atau keuntungan yang berguna untuk sintaksis yang baru?

pengguna949300
sumber
3
Pertanyaan tentang StackOverflow ini mungkin menarik bagi Anda: stackoverflow.com/questions/34361379/…
Vincent Savard
3
Saya bukan pakar JavaScript, tapi saya rasa constmembantu memastikan bahwa fungsi tersebut tidak didefinisikan ulang nanti.
MetaFight
Terima kasih @VincentSavard, itu sempurna, dan pada dasarnya apa yang saya harapkan: Selain "ini", dan barang-barang prototipe / kelas, tampaknya tidak ada perbedaan nyata.
user949300
3
@ user949300 Ada adalah perbedaan, satu MetaFight menyebutkan. Juga, prototipe / "hal ini" dengan cepat menjadi perbedaan kritis juga.
msanford
1
Singkat cerita: Anda harus menghargai dengan jelas dan ringkas atas manfaat tepi-kasus.
Wayne Bloss

Jawaban:

11

Pernyataan fungsi (fungsi yang disebutkan, sintaks ke-2 yang ditampilkan) diangkat ke bagian atas lingkup leksikal penuh, bahkan yang berada di belakang blok kontrol dan arbitrer, seperti ifpernyataan. Menggunakan const(seperti let) untuk mendeklarasikan variabel memberikannya ruang lingkup blok, menghentikan pengangkatan penuh (mengangkat ke blok belaka), dan memastikan tidak dapat dideklarasikan ulang.

Saat menggabungkan skrip bersama, atau menggunakan alat pembuat paket lainnya, fungsi mengangkat dapat memecah skrip yang saling bertentangan dengan cara yang sulit untuk di-debug karena gagal diam-diam. Deklarasi ulang constakan mengeluarkan pengecualian sebelum program dapat berjalan, jadi lebih mudah untuk melakukan debug.

Dandavis
sumber
Terima kasih. jawaban yang bagus. Saya terutama bekerja pada proyek JS yang lebih kecil, atau proyek server node.js di mana mereka memiliki sistem modul yang baik untuk namespacing. Tetapi hanya memulai pada proyek sisi klien yang menggunakan bundler dan ini adalah wawasan yang bagus.
user949300
2
Hanya sebuah catatan bahwa eslint no-func-assign dapat menangkap masalah redeklarasi ini.
user949300
2
Menulis kode yang memiliki sinyal membingungkan untuk mendapatkan manfaat dari bahasa yang diketik secara statis adalah alasan untuk menggunakan naskah, bukan const. Ini agak picik, IMO, untuk mulai menggunakan di constmana-mana karena alasan ini di zaman eslint, webpack, babel, dan sebagainya. Tidak ada yang menyatukan file bersama secara manual lagi untuk setidaknya satu dekade sekarang.
Wayne Bloss
2

Inilah mengapa Anda harus menggunakan function:

  1. Pensinyalannya jelas dan singkat. Ini jauh lebih bermanfaat daripada kekhawatiran mengangkat kasus tepi yang tercantum dalam jawaban lainnya.

  2. Anda benar-benar ingin mengangkat dalam modul karena seperti yang Anda lihat dari kode di bawah ini, constpernyataan tryDoTheThinggagal diam-diam dan tidak akan tertangkap sampai Anda mencoba menyebutnya.

  3. Sebagian besar junior yang saya hubungi mulai menggunakan constuntuk mendeklarasikan setiap fungsi karena ini adalah mode saat ini, seperti menggunakan spasi di atas tab atau membuat semuanya functional!!!karena "OOP buruk". Jangan lakukan itu. Anda tidak ingin menjadi pria yang mengikuti mode tanpa sepenuhnya memahami implikasinya.

via https://gist.github.com/stephenjfox/fec4c72c7f6ae254f31407295dc72074


/*
This shows that, because of block-scoping, const function references must be
invoked in-order or else things will fail silently.
const's are added the name space serially (in the order in which they appear)
and much of the body isn't declared when we first try to invoke or functions
*/


const tryDoTheThing = () => {
  console.log(`This is me trying to be awesome ${getAwesome()}`)
}


// "getAwesome is not defined", because it is referenced too early
tryDoTheThing() // comment to see the rest work


const getAwesome = () => (+((Math.random() * 10000).toString().split('.')[0]))


const doTheThing = () => {
  console.log(`This is awesome! ${getAwesome()}`)
}

doTheThing() // prints

vs.

/*
Function declarations are given two passes, where the first lifts them to
the top of the namespace, allowing "out of order" usage
*/

doTheThing();


function doTheThing() {
  console.log(`This is awesome number ${getAwesome()}`)
}

function getAwesome() {
  return (+((Math.random() * 10000).toString().split('.')[0]))
}
Wayne Bloss
sumber