Pertanyaannya diarahkan pada orang-orang yang memikirkan gaya kode dalam konteks ECMAScript 6 (Harmony) yang akan datang dan yang sudah bekerja dengan bahasa tersebut.
Dengan () => {}
dan function () {}
kami mendapatkan dua cara yang sangat mirip untuk menulis fungsi di ES6. Dalam bahasa lain, fungsi lambda sering kali membedakan diri dengan menjadi anonim, tetapi dalam ECMAScript, fungsi apa pun bisa anonim. Masing-masing dari kedua jenis memiliki domain penggunaan yang unik (yaitu ketika this
harus terikat secara eksplisit atau tidak terikat secara eksplisit). Di antara domain-domain tersebut ada sejumlah besar kasus di mana kedua notasi akan dilakukan.
Fungsi panah di ES6 memiliki setidaknya dua batasan:
- Jangan bekerja dengan
new
dan tidak dapat digunakan saat membuatprototype
- Tetap
this
terikat pada cakupan saat inisialisasi
Selain dua keterbatasan ini, fungsi panah secara teoritis dapat menggantikan fungsi biasa hampir di mana saja. Apa pendekatan yang tepat dalam menggunakannya? Haruskah fungsi panah digunakan misalnya:
- "Di mana pun mereka bekerja", yaitu di mana pun suatu fungsi tidak harus agnostik tentang
this
variabel dan kita tidak membuat objek. - hanya "di mana pun mereka dibutuhkan", yaitu pendengar acara, batas waktu, yang perlu terikat pada ruang lingkup tertentu
- dengan fungsi 'pendek' tetapi tidak dengan fungsi 'panjang'
- hanya dengan fungsi yang tidak mengandung fungsi panah lain
Apa yang saya cari adalah pedoman untuk memilih notasi fungsi yang sesuai di versi ECMAScript yang akan datang. Pedoman ini perlu jelas, sehingga dapat diajarkan kepada pengembang dalam tim, dan konsisten agar tidak memerlukan refactoring terus menerus bolak-balik dari satu notasi fungsi ke notasi fungsi lainnya.
sumber
Fixed this bound to scope at initialisation
sebagai batasan?this
adalah sesuatu yang dapat Anda lakukan dengan fungsi biasa tetapi tidak dengan fungsi panah.Fixed this bound to scope at initialisation
itu bukan batasan. :) Lihatlah artikel ini: exploringjs.com/es6/ch_arrow-functions.htmlJawaban:
Beberapa waktu yang lalu tim kami memigrasikan semua kodenya (aplikasi AngularJS berukuran sedang) ke JavaScript yang dikompilasi menggunakan
TraceurBabel . Saya sekarang menggunakan aturan praktis berikut untuk fungsi di ES6 dan seterusnya:function
dalam lingkup global dan untukObject.prototype
properti.class
untuk konstruktor objek.=>
tempat lain.Mengapa menggunakan fungsi panah hampir di semua tempat?
thisObject
dengan root. Jika bahkan callback fungsi standar tunggal dicampur dengan sekelompok fungsi panah ada kemungkinan ruang lingkup akan menjadi kacau.function
langsung muncul untuk menentukan ruang lingkup. Pengembang selalu dapat melihat pernyataan selanjutnya yang lebih tinggifunction
untuk melihat apathisObject
itu.Mengapa selalu menggunakan fungsi reguler pada lingkup global atau lingkup modul?
thisObject
.window
objek (lingkup global) yang terbaik ditangani secara eksplisit.Object.prototype
definisi yang hidup dalam lingkup global (pikirkanString.prototype.truncate
dll.) Dan yang umumnya harus bertipefunction
pula. Penggunaan yang konsistenfunction
pada lingkup global membantu menghindari kesalahan.function foo(){}
daripadaconst foo = () => {}
- khususnya di luar panggilan fungsi lainnya. (2) Nama fungsi ditampilkan dalam jejak tumpukan. Meskipun akan membosankan untuk menyebutkan setiap panggilan balik internal, memberi nama semua fungsi publik mungkin adalah ide yang bagus.Konstruktor objek
Mencoba membuat instantiate fungsi panah melempar pengecualian:
Salah satu keuntungan utama fungsi daripada fungsi panah adalah fungsi tersebut berfungsi ganda sebagai konstruktor objek:
Namun, definisi kelas konsep 2 ES Harmony identik secara fungsional hampir sama kompaknya:
Saya berharap bahwa penggunaan notasi sebelumnya pada akhirnya akan patah semangat. Notasi konstruktor objek masih dapat digunakan oleh beberapa untuk pabrik objek anonim sederhana di mana objek dihasilkan secara terprogram, tetapi tidak untuk banyak hal lain.
Di mana konstruktor objek diperlukan, seseorang harus mempertimbangkan mengubah fungsi menjadi
class
seperti yang ditunjukkan di atas. Sintaks berfungsi dengan fungsi / kelas anonim juga.Keterbacaan fungsi panah
Argumen terbaik untuk tetap menggunakan fungsi biasa - ruang lingkup keselamatan terkutuk - adalah bahwa fungsi panah kurang dapat dibaca daripada fungsi biasa. Jika kode Anda tidak berfungsi di tempat pertama, maka fungsi panah mungkin tidak diperlukan, dan ketika fungsi panah tidak digunakan secara konsisten, mereka terlihat jelek.
ECMAScript telah berubah sedikit sejak ECMAScript 5.1 memberi kami fungsional
Array.forEach
,Array.map
dan semua fitur pemrograman fungsional ini membuat kami menggunakan fungsi di mana for-loop akan digunakan sebelumnya. JavaScript Asynchronous sudah cukup lama. ES6 juga akan mengirimkanPromise
objek, yang berarti lebih banyak fungsi anonim. Tidak ada jalan kembali untuk pemrograman fungsional. Dalam JavaScript fungsional, fungsi panah lebih disukai daripada fungsi biasa.Ambil contoh ini (terutama membingungkan) sepotong kode 3 :
Bagian kode yang sama dengan fungsi reguler:
Sementara salah satu fungsi panah dapat digantikan oleh fungsi standar, akan ada sangat sedikit yang bisa didapat dari melakukannya. Versi mana yang lebih mudah dibaca? Saya akan mengatakan yang pertama.
Saya pikir pertanyaan apakah menggunakan fungsi panah atau fungsi biasa akan menjadi kurang relevan seiring waktu. Sebagian besar fungsi akan menjadi metode kelas, yang menghilangkan
function
kata kunci, atau mereka akan menjadi kelas. Fungsi akan tetap digunakan untuk menambal kelas melaluiObject.prototype
. Sementara itu saya sarankan memesanfunction
kata kunci untuk apa pun yang benar-benar harus menjadi metode kelas atau kelas.Catatan
extend
kata kunci. Perbedaan kecil adalah bahwa deklarasi kelas adalah konstanta, sedangkan deklarasi fungsi tidak.sumber
function
adalah ketika Anda tidak inginthis
terikat, bukan? Skenario saya yang paling umum untuk ini adalah peristiwa, di mana Anda mungkin inginthis
merujuk ke objek (biasanya simpul DOM) yang memicu acara.=>
akhirnya tampak lebih baik seiring waktu. Saya ragu bahwa non-programmer akan merasa sangat berbeda tentang dua contoh. Jika Anda menulis kode ES2016, biasanya Anda tidak akan berakhir menggunakan banyak fungsi panah ini. Dalam contoh ini, menggunakan async / await dan pemahaman array, Anda akan berakhir hanya dengan satu fungsi panah dalamreduce()
panggilan.Menurut proposal itu , panah bertujuan "untuk mengatasi dan menyelesaikan beberapa titik sakit tradisional yang umum
Function Expression
." Mereka bermaksud memperbaiki masalah dengan mengikatthis
secara leksikal dan menawarkan sintaksis singkat.Namun,
this
leksikalOleh karena itu, fungsi panah menciptakan peluang untuk kebingungan dan kesalahan, dan harus dikeluarkan dari kosakata programmer JavaScript, diganti dengan
function
secara eksklusif.Mengenai leksikal
this
this
bermasalah:Fungsi panah bermaksud untuk memperbaiki masalah di mana kita perlu mengakses properti
this
di dalam panggilan balik. Sudah ada beberapa cara untuk melakukan itu: Seseorang dapat menetapkanthis
untuk variabel, menggunakanbind
, atau menggunakan argumen ke-3 yang tersedia padaArray
metode agregat. Namun panah tampaknya merupakan solusi yang paling sederhana, sehingga metode ini dapat di refactored seperti ini:Namun, pertimbangkan jika kode tersebut menggunakan pustaka seperti jQuery, yang metodenya mengikat
this
secara khusus. Sekarang, ada duathis
nilai yang harus dihadapi:Kita harus menggunakan
function
agareach
mengikatthis
secara dinamis. Kami tidak dapat menggunakan fungsi panah di sini.Berurusan dengan banyak
this
nilai juga bisa membingungkan, karena sulit untuk mengetahuithis
penulis mana yang dibicarakan:Apakah penulis sebenarnya bermaksud menelepon
Book.prototype.reformat
? Atau apakah dia lupa mengikatthis
, dan berniat meneleponReader.prototype.reformat
? Jika kita mengubah penangan ke fungsi panah, kita juga akan bertanya-tanya apakah penulis menginginkan dinamikathis
, namun memilih panah karena sesuai pada satu baris:Seseorang dapat berpose: "Apakah luar biasa bahwa panah kadang-kadang bisa menjadi fungsi yang salah untuk digunakan? Mungkin jika kita jarang membutuhkan dinamika
this
nilai-nilai , maka sebagian besar waktu akan tetap oke untuk menggunakan panah."Tetapi tanyakan pada diri sendiri ini: "Apakah 'layak' untuk men-debug kode dan menemukan bahwa hasil dari kesalahan dibawa oleh 'kasus tepi?'" Saya lebih suka menghindari masalah bukan hanya sebagian besar waktu, tetapi 100% dari waktu.
Ada cara yang lebih baik: Selalu gunakan
function
(jadithis
selalu bisa terikat secara dinamis), dan selalu referensithis
melalui variabel. Variabel leksikal dan mengasumsikan banyak nama. Menetapkanthis
ke variabel akan membuat niat Anda jelas:Selain itu, selalu menugaskan
this
ke variabel (bahkan ketika ada satuthis
atau tidak ada fungsi lain) memastikan niat seseorang tetap jelas bahkan setelah kode diubah.Juga, dinamis
this
hampir tidak luar biasa. jQuery digunakan di lebih dari 50 juta situs web (pada tulisan ini pada Februari 2016). Berikut adalah API lain yang mengikatthis
secara dinamis:this
.this
.this
.EventTarget
denganthis
.this
.(Statistik via http://trends.builtwith.com/javascript/jQuery dan https://www.npmjs.com .)
Anda kemungkinan sudah membutuhkan
this
binding dinamis .Leksikal
this
kadang-kadang diharapkan, tetapi kadang-kadang tidak; sama seperti dinamikathis
kadang-kadang diharapkan, tetapi kadang tidak. Syukurlah, ada cara yang lebih baik, yang selalu menghasilkan dan mengomunikasikan ikatan yang diharapkan.Mengenai sintaks singkat
Fungsi panah berhasil menyediakan "bentuk sintaksis pendek" untuk fungsi. Tetapi apakah fungsi yang lebih pendek ini akan membuat Anda lebih sukses?
Apakah
x => x * x
"lebih mudah dibaca" daripadafunction (x) { return x * x; }
? Mungkin begitu, karena lebih mungkin menghasilkan satu baris kode pendek. Mengakses pada Dyson Pengaruh kecepatan membaca dan panjang garis pada efektivitas membaca dari layar ,Pembenaran serupa dibuat untuk operator bersyarat (ternary), dan untuk
if
pernyataan garis tunggal .Namun, apakah Anda benar-benar menulis fungsi matematika sederhana yang diiklankan dalam proposal ? Domain saya bukan matematika, jadi subrutin saya jarang begitu elegan. Sebaliknya, saya biasanya melihat fungsi panah melanggar batas kolom, dan membungkus ke baris lain karena editor atau panduan gaya, yang membatalkan "keterbacaan" oleh definisi Dyson.
Seseorang mungkin berpose, "Bagaimana kalau hanya menggunakan versi pendek untuk fungsi pendek, bila memungkinkan?" Tetapi sekarang aturan gaya bertentangan dengan batasan bahasa: "Cobalah menggunakan notasi fungsi sesingkat mungkin, ingatlah bahwa kadang-kadang hanya notasi terpanjang yang akan mengikat
this
seperti yang diharapkan." Penggabungan seperti itu membuat anak panah rentan terhadap penyalahgunaan.Ada banyak masalah dengan sintaks fungsi panah:
Kedua fungsi ini valid secara sintaksis. Tetapi
doSomethingElse(x);
tidak ada di dalam tubuhb
, itu hanya pernyataan tingkat atas yang indentasi buruk.Ketika memperluas ke bentuk blok, tidak ada lagi yang tersirat
return
, yang orang bisa lupa untuk mengembalikan. Tetapi ungkapan itu mungkin hanya dimaksudkan untuk menghasilkan efek samping, jadi siapa yang tahu jika diperlukan eksplisitreturn
untuk maju?Apa yang mungkin dimaksudkan sebagai parameter lainnya dapat diurai sebagai operator spread:
Tugas dapat dikacaukan dengan argumen default:
Blok terlihat seperti objek:
Apa artinya ini?
Apakah penulis bermaksud membuat no-op, atau fungsi yang mengembalikan objek kosong? (Dengan mengingat hal ini, haruskah kita menempatkan
{
setelah=>
? Haruskah kita membatasi diri kita hanya pada sintaks ekspresi? Itu akan semakin mengurangi frekuensi panah.)=>
terlihat seperti<=
dan>=
:Untuk memunculkan ekspresi fungsi panah dengan segera, seseorang harus menempatkan
()
di luar, namun menempatkan()
di dalam adalah valid dan bisa disengaja.Meskipun, jika seseorang menulis
(() => doSomething()());
dengan maksud untuk menulis ekspresi fungsi yang segera dipanggil, tidak ada yang akan terjadi.Sulit untuk berpendapat bahwa fungsi panah "lebih dapat dimengerti" dengan semua kasus di atas dalam pikiran. Seseorang dapat mempelajari semua aturan khusus yang diperlukan untuk menggunakan sintaks ini. Apakah ini benar-benar layak?
Sintaksnya
function
digeneralisasikan secara tidak terduga. Untuk menggunakanfunction
secara eksklusif berarti bahasa itu sendiri mencegah seseorang dari menulis kode yang membingungkan. Untuk menulis prosedur yang harus dipahami secara sintaksis dalam semua kasus, saya memilihfunction
.Tentang pedoman
Anda meminta pedoman yang harus "jelas" dan "konsisten." Menggunakan fungsi panah pada akhirnya akan menghasilkan kode yang valid secara sintaksis, tidak logis secara logis, dengan kedua bentuk fungsi saling terkait, bermakna dan sewenang-wenang. Karena itu, saya menawarkan yang berikut:
Pedoman untuk Notasi Fungsi di ES6:
function
.this
ke variabel. Jangan gunakan() => {}
.sumber
self
bukan ini. Perangkap fungsi tanda panah yang Anda nyatakan juga semuanya valid, dan standar yang sama seperti pada pernyataan lain yang bisa digunakan tanpa kawat gigi pasti berlaku di sini juga; jika tidak, saya pikir dengan argumen Anda, orang juga bisa menganjurkan fungsi panah di mana-mana.this
adalah masalah Javascript. Alih-alih terikat secara implisit,this
harus disahkan sebagai argumen eksplisit.Fungsi panah dibuat untuk menyederhanakan fungsi
scope
dan menyelesaikanthis
kata kunci dengan membuatnya lebih sederhana. Mereka menggunakan=>
sintaksis, yang terlihat seperti panah.Catatan: Itu tidak menggantikan fungsi yang ada. Jika Anda mengganti setiap sintaks fungsi dengan fungsi panah, itu tidak akan berfungsi dalam semua kasus.
Mari kita lihat sintaks ES5 yang ada, Jika
this
kata kunci ada di dalam metode objek (fungsi yang dimiliki objek), apa yang akan dirujuk?Cuplikan di atas akan merujuk ke
object
dan mencetak nama"RajiniKanth"
. Mari jelajahi cuplikan di bawah ini dan lihat apa yang akan ditunjukkan di sini.Sekarang bagaimana dengan jika
this
kata kunci ada di dalammethod’s function
?Di sini ini akan merujuk
window object
daripadainner function
yang jatuh dariscope
. Karenathis
, selalu referensi pemilik fungsi itu, untuk kasus ini - karena sekarang di luar ruang lingkup - jendela / objek global.Ketika itu berada di dalam
object
metode an -function
pemilik adalah objek. Jadi kata kunci ini terikat ke objek. Namun ketika itu berada di dalam suatu fungsi, baik berdiri sendiri atau dalam metode lain, itu akan selalu merujuk padawindow/global
objek.Ada beberapa cara untuk menyelesaikan masalah ini dengan
ES5
sendirinya, mari kita selidiki sebelum menyelam ke fungsi ES6 arrow tentang cara mengatasinya.Biasanya Anda akan, membuat variabel di luar fungsi dalam metode ini. Sekarang
‘forEach’
metode mendapatkan akses kethis
dan dengan demikianobject’s
properti dan nilainya.gunakan
bind
untuk melampirkanthis
kata kunci yang merujuk pada metode kemethod’s inner function
.Sekarang dengan
ES6
fungsi panah, kita dapat menanganilexical scoping
masalah dengan cara yang lebih sederhana.Arrow functions
lebih seperti pernyataan fungsi, kecuali bahwa merekabind
ini untukparent scope
. Jika argumenarrow function is in top scope
,this
akan merujukwindow/global scope
, sedangkan fungsi panah di dalam fungsi biasa akan memiliki argumen ini sama dengan fungsi luarnya.Dengan
arrow
fungsithis
terikat ke melampirkanscope
pada waktu pembuatan dan tidak dapat diubah. Operator baru, ikat, panggil, dan terapkan tidak berpengaruh pada ini.Dalam contoh di atas, kami kehilangan kendali atas hal ini. Kita dapat memecahkan contoh di atas dengan menggunakan referensi variabel
this
atau menggunakanbind
. Dengan ES6, ia menjadi lebih mudah dalam mengelola apathis
yang terikat padanyalexical scoping
.Ketika tidak ke Arrow fungsi
Di dalam objek literal.
Actor.getName
didefinisikan dengan fungsi panah, tetapi pada pemanggilan peringatan itu tidak terdefinisi karenathis.name
adalahundefined
sebagai konteks tetapwindow
.Itu terjadi karena fungsi panah mengikat konteks secara leksikal dengan
window object
... yaitu lingkup luar. Eksekusithis.name
setara denganwindow.name
, yang tidak terdefinisi.Prototipe objek
Aturan yang sama berlaku ketika mendefinisikan metode pada a
prototype object
. Alih-alih menggunakan fungsi panah untuk mendefinisikan metode sayCatName, yang membawa kesalahancontext window
:Memohon konstruktor
this
dalam doa konstruksi adalah objek yang baru dibuat. Saat menjalankan Fn baru (), konteks objekconstructor Fn
adalah baru:this instanceof Fn === true
.this
adalah pengaturan dari konteks melampirkan, yaitu lingkup luar yang membuatnya tidak ditugaskan ke objek yang baru dibuat.Panggilan balik dengan konteks dinamis
Fungsi panah mengikat
context
statik pada deklarasi dan tidak mungkin membuatnya dinamis. Melampirkan pendengar acara ke elemen DOM adalah tugas umum dalam pemrograman sisi klien. Suatu peristiwa memicu fungsi handler dengan ini sebagai elemen target.this
adalah jendela dalam fungsi panah yang didefinisikan dalam konteks global. Ketika suatu peristiwa klik terjadi, browser mencoba untuk memanggil fungsi handler dengan konteks tombol, tetapi fungsi panah tidak mengubah konteks yang telah ditentukan sebelumnya.this.innerHTML
setara denganwindow.innerHTML
dan tidak masuk akal.Anda harus menerapkan ekspresi fungsi, yang memungkinkan untuk mengubahnya tergantung pada elemen target:
Ketika pengguna mengklik tombol, ini dalam fungsi penangan adalah tombol. Dengan demikian
this.innerHTML = 'Clicked button'
memodifikasi teks tombol dengan benar untuk mencerminkan status yang diklik.Referensi: https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/
sumber
using bind to attach the this keyword that refers to the method to the method’s inner function.
memiliki kesalahan sintaksis.var Actor = { name: 'RajiniKanth', movies: ['Kabali', 'Sivaji', 'Baba'], showMovies: function() { this.movies.forEach(function(movie){ alert(this.name + ' has acted in ' + movie); }.bind(this)) } }; Actor.showMovies();
Penggunaan: Semua fungsi ES5 harus diganti dengan fungsi panah ES6 kecuali dalam skenario berikut:
Fungsi panah TIDAK boleh digunakan:
this
/arguments
dalam suatu fungsithis
/arguments
sendiri, mereka bergantung pada konteks luarnya.constructor
this
.this
(yang seharusnya menjadi objek itu sendiri).Mari kita memahami beberapa varian fungsi panah untuk memahami lebih baik:
Varian 1 : Ketika kita ingin melewatkan lebih dari satu argumen ke suatu fungsi dan mengembalikan beberapa nilai darinya.
Versi ES5 :
Versi ES6 :
Catatan:
function
kata kunci TIDAK diperlukan.=>
Dibutuhkan.{}
bersifat opsional, ketika kami tidak menyediakan{}
return
secara implisit ditambahkan oleh JavaScript dan ketika kami menyediakan{}
kami perlu menambahkanreturn
jika kami membutuhkannya.Varian 2 : Ketika kita ingin melewatkan HANYA satu argumen ke suatu fungsi dan mengembalikan beberapa nilai darinya.
Versi ES5 :
Versi ES6 :
Catatan: Saat melewati hanya satu argumen, kita dapat menghilangkan tanda kurung
()
.Varian 3 : Ketika kita TIDAK ingin meneruskan argumen apa pun ke suatu fungsi dan TIDAK ingin mengembalikan nilai apa pun.
Versi ES5 :
Versi ES6 :
Varian 4 : Ketika kita ingin secara eksplisit kembali dari fungsi panah.
Versi ES6 :
Varian 5 : Saat kita ingin mengembalikan objek dari fungsi panah.
Versi ES6 :
Catatan: Kita perlu membungkus objek dalam tanda kurung
()
jika tidak, JavaScript tidak dapat membedakan antara blok dan objek.Varian 6 : Fungsi panah TIDAK memiliki
arguments
(array seperti objek) sendiri, mereka bergantung pada konteks luararguments
.Versi ES6 :
Catatan:
foo
adalah fungsi ES5, denganarguments
array seperti objek dan argumen dilewatkan ke itu2
sehinggaarguments[0]
untukfoo
adalah 2.abc
adalah ES6 panah fungsi karena TIDAK memiliki itu sendiriarguments
karena itu mencetakarguments[0]
darifoo
konteks luar itu sebagai gantinya.Varian 7 : Fungsi panah TIDAK miliki
this
sendiri, mereka bergantung pada konteks luar untukthis
Versi ES5 :
Catatan: Callback yang diteruskan ke setTimeout adalah fungsi ES5 dan memiliki itu sendiri
this
yang tidak terdefinisi diuse-strict
lingkungan maka kita mendapatkan output:Versi ES6 :
Catatan: Callback yang diteruskan ke
setTimeout
adalah fungsi panah ES6 dan TIDAK memiliki itu sendirithis
sehingga mengambilnya dari konteks luarnyagreetUser
yang memilikithis
yangobj6
karenanya kita mendapatkan output:Lain-lain: Kami tidak dapat menggunakan
new
dengan fungsi panah. Fungsi panah tidak memilikiprototype
properti. Kami TIDAK memiliki pengikatanthis
kapan fungsi panah dipanggil melaluiapply
ataucall
.sumber
Selain jawaban yang bagus sejauh ini, saya ingin menyajikan alasan yang sangat berbeda mengapa fungsi panah dalam arti tertentu secara fundamental lebih baik daripada fungsi JavaScript "biasa". Demi diskusi, mari kita asumsikan sementara kita menggunakan pemeriksa tipe seperti TypeScript atau "Aliran" Facebook. Pertimbangkan modul mainan berikut ini, yang merupakan kode ECMAScript 6 yang valid plus anotasi jenis aliran: (Saya akan memasukkan kode yang tidak diketik, yang secara realistis dihasilkan dari Babel, pada akhir jawaban ini, sehingga benar-benar dapat dijalankan.)
Sekarang lihat apa yang terjadi ketika kita menggunakan kelas C dari modul yang berbeda, seperti ini:
Seperti yang Anda lihat, pemeriksa tipe gagal di sini: f2 seharusnya mengembalikan nomor, tetapi mengembalikan string!
Lebih buruk lagi, tampaknya tidak ada pemeriksa tipe yang dapat menangani fungsi JavaScript biasa (non-panah), karena "ini" dari f2 tidak muncul dalam daftar argumen f2, sehingga jenis yang diperlukan untuk "ini" tidak dapat ditambahkan sebagai anotasi ke f2.
Apakah masalah ini juga memengaruhi orang yang tidak menggunakan checker tipe? Saya kira begitu, karena bahkan ketika kita tidak memiliki tipe statis, kita berpikir seolah-olah mereka ada di sana. ("Parameter pertama harus berupa angka, yang kedua adalah string" dll.) Dokumen "this" tersembunyi yang mungkin atau mungkin tidak digunakan dalam tubuh fungsi membuat pembukuan mental kita lebih sulit.
Ini adalah versi untyped runnable, yang akan diproduksi oleh Babel:
sumber
Saya masih mendukung semua yang saya tulis dalam jawaban pertama saya di utas ini. Namun, pendapat saya tentang gaya kode telah berkembang sejak saat itu, jadi saya punya jawaban baru untuk pertanyaan ini yang dibangun di atas yang terakhir.
Mengenai leksikal
this
Dalam jawaban terakhir saya, saya sengaja menghindari keyakinan mendasar yang saya pegang tentang bahasa ini, karena tidak terkait langsung dengan argumen yang saya buat. Meskipun demikian, tanpa ini dinyatakan secara eksplisit, saya bisa mengerti mengapa banyak orang menolak keras rekomendasi saya untuk tidak menggunakan panah, ketika mereka menemukan panah sangat berguna.
Keyakinan saya adalah ini: kita seharusnya tidak menggunakannya
this
. Oleh karena itu, jika seseorang dengan sengaja menghindari penggunaanthis
dalam kodenya, maka fitur "leksikalthis
" panah adalah sedikit atau tidak bernilai. Juga, di bawah premis yangthis
merupakan hal yang buruk, perlakuan panah terhadapthis
kurang dari "hal yang baik;" alih-alih, ini lebih merupakan bentuk kontrol kerusakan untuk fitur bahasa buruk lainnya.Saya pikir ini tidak terjadi pada beberapa orang, tetapi bahkan bagi mereka yang melakukannya, mereka harus selalu menemukan diri mereka bekerja dalam basis kode di mana
this
muncul ratusan kali per file, dan sedikit (atau banyak) kontrol kerusakan adalah semua orang yang berakal bisa berharap. Jadi panah bisa baik, dengan cara, ketika mereka membuat situasi yang buruk menjadi lebih baik.Bahkan jika lebih mudah untuk menulis kode dengan
this
panah daripada tanpa mereka, aturan untuk menggunakan panah tetap sangat kompleks (lihat: utas saat ini). Dengan demikian, pedoman tidak "jelas" atau "konsisten," seperti yang Anda minta. Bahkan jika programmer tahu tentang ambiguitas panah, saya pikir mereka mengangkat bahu dan menerimanya, karena nilai leksikalthis
membayangi mereka.Semua ini adalah kata pengantar untuk realisasi berikut: jika seseorang tidak menggunakan
this
, maka ambiguitas tentangthis
panah yang biasanya menyebabkan menjadi tidak relevan. Panah menjadi lebih netral dalam konteks ini.Mengenai sintaks singkat
Ketika saya menulis jawaban pertama saya, saya berpendapat bahwa bahkan kepatuhan terhadap praktik terbaik adalah harga yang pantas untuk dibayar jika itu berarti saya dapat menghasilkan kode yang lebih sempurna. Tapi saya akhirnya menyadari bahwa kesederhanaan dapat berfungsi sebagai bentuk abstraksi yang dapat meningkatkan kualitas kode juga - cukup sehingga untuk membenarkan penyimpangan dari praktik terbaik kadang-kadang.
Dengan kata lain: sialan, saya juga ingin fungsi satu-liner!
Tentang pedoman
Dengan kemungkinan
this
fungsi panah-netral, dan kesederhanaan yang layak dikejar, saya menawarkan pedoman yang lebih lunak berikut:Pedoman untuk Notasi Fungsi di ES6:
this
.sumber
Saya lebih suka menggunakan fungsi panah setiap saat di mana akses ke lokal
this
tidak diperlukan, karena fungsi panah tidak mengikat sendiri ini, argumen, super, atau new.target .sumber
Secara sederhana,
Contoh lain:
Jawab: Konsol akan mencetak 20.
Alasannya adalah setiap kali fungsi dijalankan, stack-nya sendiri dibuat, dalam
ex
fungsi contoh ini dieksekusi dengannew
operator sehingga konteks akan dibuat, dan ketikainner
dieksekusi JS akan membuat stack baru dan menjalankaninner
fungsiglobal context
meskipun ada konteks lokal.Jadi, jika kita ingin
inner
fungsi memiliki konteks lokal,ex
maka kita perlu mengikat konteks ke fungsi internal.Panah memecahkan masalah ini, alih-alih mengambil
Global context
mereka mengambillocal context
jika ada. Dalamgiven example,
itu akan mengambilnew ex()
sebagaithis
.Jadi, dalam semua kasus di mana mengikat adalah Arrows eksplisit menyelesaikan masalah secara default.
sumber
Fungsi panah atau Lambdas, diperkenalkan dalam ES 6. Terlepas dari keanggunannya dalam sintaks minimal, perbedaan fungsional yang paling menonjol adalah pelingkupan
this
di dalam fungsi panahKeterbatasan Panah-Berfungsi sebagai metode pada Objek
Dalam kasus
objA.print()
ketikaprint()
metode didefinisikan menggunakan biasafunction
, itu bekerja dengan menyelesaikanthis
dengan benarobjA
untuk permohonan metode tetapi gagal ketika didefinisikan sebagai=>
fungsi panah . Itu karenathis
dalam fungsi reguler ketika dipanggil sebagai metode pada objek (objA
), adalah objek itu sendiri. Namun, dalam kasus fungsi panah,this
secara leksikal terikat padathis
lingkup lingkup di mana ia didefinisikan (global / Window dalam kasus kami) dan tetap itu tetap sama selama doa sebagai metode aktifobjA
.Keuntungan dari panah-fungsi atas fungsi biasa dalam metode (s) dari suatu objek TETAPI hanya ketika
this
diharapkan diperbaiki & terikat pada definisi waktu.Dalam kasus di
objB.print()
manaprint()
metode didefinisikan sebagai fungsi yang memanggilconsole.log(
[$ {this.id} -> {this.name}] secara)
serempak sebagai panggilan balik aktifsetTimeout
,this
diselesaikan dengan benarobjB
ketika fungsi panah digunakan sebagai panggilan balik tetapi gagal ketika panggilan balik didefinisikan sebagai fungsi biasa. Itu karena=>
fungsi panah dilewatkan untuksetTimeout(()=>..)
ditutupthis
secara leksikal dari induknya yaitu. doaobjB.print()
yang didefinisikan itu. Dalam lain-kata, panah=>
fungsi berlalu ke untuksetTimeout(()==>...
terikatobjB
sebagai yangthis
karena di doaobjB.print()
this
ituobjB
sendiri.Kita dapat dengan mudah menggunakan
Function.prototype.bind()
, untuk membuat panggilan balik didefinisikan sebagai fungsi biasa berfungsi, dengan mengikatnya ke yang benarthis
.Namun, fungsi panah berguna dan lebih sedikit kesalahan rawan untuk kasus async call-backs di mana kita tahu
this
pada saat definisi fungsi yang didapat dan harus terikat.Batasan Fungsi Panah di mana ini perlu diubah di seluruh doa
Kapan saja, kita membutuhkan fungsi yang
this
dapat diubah pada saat doa, kita tidak bisa menggunakan fungsi panah.Tidak satu pun dari yang di atas akan berfungsi dengan fungsi panah
const print = () => { console.log(
[$ {this.id} -> {this.name}]);}
karenathis
tidak dapat diubah dan akan tetap terikat denganthis
lingkup lingkup terlampir di mana ia didefinisikan (global / Window). Dalam semua contoh ini, kami memanggil fungsi yang sama dengan objek yang berbeda (obj1
danobj2
) satu demi satu, keduanya dibuat setelahprint()
fungsi tersebut dinyatakan.Ini adalah contoh yang dibuat-buat, tapi mari kita pikirkan beberapa contoh kehidupan nyata. Jika kita harus menulis
reduce()
metode kita mirip dengan yang bekerjaarrays
, kita lagi tidak dapat mendefinisikannya sebagai lambda, karena itu perlu disimpulkanthis
dari konteks doa, yaitu. array yang dipanggilUntuk alasan ini,
constructor
fungsi tidak pernah dapat didefinisikan sebagai fungsi panah, karenathis
untuk fungsi konstruktor tidak dapat ditetapkan pada saat deklarasi. Setiap kali fungsi konstruktor dipanggil dengannew
kata kunci, objek baru dibuat yang kemudian terikat pada permintaan tertentu.Juga ketika ketika kerangka kerja atau sistem menerima fungsi panggilan balik yang akan dipanggil nanti dengan konteks dinamis
this
, kita tidak bisa menggunakan fungsi panah karena lagithis
mungkin perlu berubah dengan setiap doa. Situasi ini biasanya muncul dengan penangan acara DOMIni juga merupakan alasan mengapa dalam kerangka kerja seperti Angular 2+ dan Vue.js mengharapkan metode pengikatan komponen-templat menjadi fungsi / metode biasa
this
karena permohonan mereka dikelola oleh kerangka kerja untuk fungsi pengikatan. (Angular menggunakan Zone.js untuk mengelola konteks async untuk pemanggilan fungsi pengikatan tampilan-templat).Di sisi lain, di Bereaksi , ketika kita ingin meneruskan metode komponen sebagai event-handler misalnya
<input onChange={this.handleOnchange} />
kita harus mendefinisikanhandleOnchanage = (event)=> {this.props.onInputChange(event.target.value);}
sebagai fungsi panah seperti untuk setiap doa, kita ingin ini menjadi contoh yang sama dari komponen yang menghasilkan JSX untuk di-render Elemen DOM.Artikel ini juga dapat ditayangkan di publikasi Medium saya . Jika Anda menyukai artile, atau memiliki komentar dan saran, silakan bertepuk tangan atau meninggalkan komentar di Medium .
sumber