Saya menemukan fitur parameter bernama di C # cukup berguna dalam beberapa kasus.
calculateBMI(70, height: 175);
Apa yang dapat saya gunakan jika saya menginginkan ini dalam JavaScript?
Yang tidak saya inginkan adalah ini:
myFunction({ param1: 70, param2: 175 });
function myFunction(params){
// Check if params is an object
// Check if the parameters I need are non-null
// Blah blah
}
Pendekatan itu sudah saya gunakan. Apakah ada cara lain?
Saya baik-baik saja menggunakan perpustakaan apa pun untuk melakukan ini.
javascript
function
optional-parameters
named-parameters
Robin Maben
sumber
sumber
Function
bisa dilakukan di javascript.Function
di Javascript tidak dapat mengubah sintaksis inti JavascriptcalculateBMI(70, /*height:*/ 175);
, (2) berikan objekcalculateBMI(70, {height: 175})
, atau (3) gunakan konstantaconst height = 175; calculateBMI(70, height);
.Jawaban:
ES2015 dan yang lebih baru
Dalam ES2015, perusakan parameter dapat digunakan untuk mensimulasikan parameter bernama. Ini akan meminta penelepon untuk melewati objek, tetapi Anda dapat menghindari semua pemeriksaan di dalam fungsi jika Anda juga menggunakan parameter default:
ES5
Ada cara untuk mendekati apa yang Anda inginkan, tetapi didasarkan pada output
Function.prototype.toString
[ES5] , yang implementasinya tergantung pada tingkat tertentu, sehingga mungkin tidak kompatibel dengan browser.Idenya adalah untuk mem-parsing nama parameter dari representasi string dari fungsi sehingga Anda dapat mengaitkan properti suatu objek dengan parameter yang sesuai.
Panggilan fungsi kemudian bisa terlihat seperti
di mana
a
danb
adalah argumen posisi dan argumen terakhir adalah objek dengan argumen bernama.Sebagai contoh:
Yang akan Anda gunakan sebagai:
DEMO
Ada beberapa kelemahan dari pendekatan ini (Anda telah diperingatkan!):
undefined
(yang berbeda dari tidak memiliki nilai sama sekali). Itu berarti Anda tidak dapat menggunakanarguments.length
untuk menguji berapa banyak argumen yang telah diajukan.Alih-alih memiliki fungsi membuat wrapper, Anda juga bisa memiliki fungsi yang menerima fungsi dan berbagai nilai sebagai argumen, seperti
atau bahkan meluas
Function.prototype
sehingga Anda bisa melakukan:sumber
Object.defineProperty
dan mengaturenumerable
kefalse
). Seseorang harus selalu berhati-hati ketika memperluas benda-benda asli. Seluruh pendekatan terasa agak berantakan, jadi saya tidak akan berharap itu berfungsi sekarang dan selamanya;)undefined
vs "tidak ada nilai", dapat ditambahkan bahwa ini adalah cara kerja nilai default fungsi JS - memperlakukanundefined
sebagai nilai yang hilang.Tidak - pendekatan objek adalah jawaban JavaScript untuk ini. Tidak ada masalah dengan ini asalkan fungsi Anda mengharapkan objek daripada params terpisah.
sumber
Masalah ini telah membuat saya kesal hewan peliharaan selama beberapa waktu. Saya seorang programmer berpengalaman dengan banyak bahasa di bawah ikat pinggang saya. Salah satu bahasa favorit saya yang senang saya gunakan adalah Python. Python mendukung parameter bernama tanpa tipuan .... Karena saya mulai menggunakan Python (beberapa waktu lalu) semuanya menjadi lebih mudah. Saya percaya bahwa setiap bahasa harus mendukung parameter bernama, tetapi itu tidak terjadi.
Banyak orang mengatakan untuk hanya menggunakan trik "Lulus objek" sehingga Anda telah menetapkan parameter.
Dan itu bekerja dengan baik, kecuali ..... ketika datang ke sebagian besar IDE di luar sana, banyak dari kita pengembang bergantung pada tipe / petunjuk petunjuk dalam IDE kami. Saya pribadi menggunakan PHP Storm (Bersama dengan JetBrains IDE lainnya seperti PyCharm untuk python dan AppCode untuk Objective C)
Dan masalah terbesar dengan menggunakan trik "Lulus objek" adalah bahwa ketika Anda memanggil fungsi, IDE memberi Anda petunjuk jenis tunggal dan hanya itu ... Bagaimana kita bisa tahu parameter dan tipe apa yang harus dimasukkan ke dalam objek arg1?
Jadi ... trik "Lewati sebuah objek" tidak berfungsi untuk saya ... Itu sebenarnya menyebabkan lebih banyak sakit kepala karena harus melihat setiap fungsi docblock sebelum saya tahu parameter apa yang diharapkan fungsi tersebut .... Tentu, itu bagus untuk ketika Anda mempertahankan kode yang ada, tetapi mengerikan untuk menulis kode baru.
Nah, ini adalah teknik yang saya gunakan .... Sekarang, mungkin ada beberapa masalah dengan itu, dan beberapa pengembang mungkin mengatakan saya salah, dan saya memiliki pikiran terbuka mengenai hal-hal ini ... Saya selalu ingin melihat cara yang lebih baik untuk menyelesaikan tugas ... Jadi, jika ada masalah dengan teknik ini, maka komentar dipersilahkan.
Dengan cara ini, saya memiliki yang terbaik dari kedua dunia ... kode baru mudah untuk ditulis karena IDE saya memberi saya semua argumen argumen yang tepat ... Dan, sambil mempertahankan kode nanti, saya bisa melihat sekilas, tidak hanya nilai diteruskan ke fungsi, tetapi juga nama argumen. Satu-satunya overhead yang saya lihat adalah mendeklarasikan nama argumen Anda sebagai variabel lokal agar tidak mencemari namespace global. Tentu, ini sedikit mengetik ekstra, tetapi sepele dibandingkan dengan waktu yang diperlukan untuk mencari dokumen saat menulis kode baru atau mempertahankan kode yang ada.
sumber
myFunc(/*arg1*/ 'Param1', /*arg2*/ 'Param2');
itu lebih baik daripadamyFunc(arg1='Param1', arg2='Param2');
, karena itu tidak memiliki kesempatan untuk menipu pembaca daripada yang terjadi argumen bernamaJika Anda ingin memperjelas masing-masing parameter, bukan hanya menelepon
mengapa tidak melakukan yang berikut ini
tentu saja, ini merupakan baris kode tambahan, tetapi menang pada keterbacaan.
sumber
someFunction(height: 115);
tetapi jika Anda menulissomeFunction(height);
Anda sebenarnya sedang mengatur lebar.someFunction(width = 70, height = 115);
. Variabel dideklarasikan di bagian atas ruang lingkup saat ini dalam kode JavaScript yang dihasilkan.Cara lain adalah dengan menggunakan atribut dari objek yang sesuai, misalnya seperti:
Tentu saja untuk contoh yang dibuat ini agak tidak berarti. Tetapi dalam kasus-kasus di mana fungsinya terlihat
mungkin lebih bermanfaat. Itu juga dapat dikombinasikan dengan ide "parameterfy" untuk membuat objek seperti itu dari fungsi yang ada dengan cara yang umum. Itu untuk setiap parameter itu akan membuat anggota yang dapat mengevaluasi ke versi fungsi yang dievaluasi parsial.
Ide ini tentu saja terkait dengan Schonfinkeling alias Currying.
sumber
Ada cara lain. Jika Anda melewati objek dengan referensi, properti objek itu akan muncul di lingkup lokal fungsi. Saya tahu ini berfungsi untuk Safari (belum memeriksa peramban lain) dan saya tidak tahu apakah fitur ini memiliki nama, tetapi contoh di bawah ini menggambarkan penggunaannya.
Meskipun dalam praktiknya saya tidak berpikir bahwa ini menawarkan nilai fungsional di luar teknik yang sudah Anda gunakan, ini sedikit lebih bersih secara semantik. Dan itu masih membutuhkan melewati referensi objek atau objek literal.
sumber
Mencoba Node-6.4.0 (process.versions.v8 = '5.0.71.60') dan Node Chakracore-v7.0.0-pre8 dan kemudian Chrome-52 (V8 = 5.2.361.49), saya perhatikan bahwa parameter bernama hampir diimplementasikan, tetapi urutan itu masih diutamakan. Saya tidak dapat menemukan apa yang dikatakan standar ECMA.
Tapi pesanan diperlukan !! Apakah itu perilaku standar?
sumber
b=10
ekspresi adalah10
, dan itulah yang diteruskan ke fungsi.f(bla=10)
juga akan bekerja (ini memberikan 10 ke variabelbla
dan meneruskan nilai ke fungsi setelahnya).a
danb
variabel dalam lingkup global sebagai efek samping.Fungsi panggilan
f
dengan parameter bernama dilewatkan sebagai objekpada dasarnya memanggil komposisinya di
f(...g(o))
mana saya menggunakan sintaks spread dang
merupakan "mengikat" peta yang menghubungkan nilai objek dengan posisi parameter mereka.Peta pengikat justru merupakan bahan yang hilang, yang bisa direpresentasikan dengan susunan kuncinya:
Perhatikan tiga bahan yang dipisahkan: fungsi, objek dengan argumen bernama dan pengikatan. Decoupling ini memungkinkan banyak fleksibilitas untuk menggunakan konstruksi ini, di mana pengikatan dapat disesuaikan secara sewenang-wenang dalam definisi fungsi dan diperpanjang secara sewenang-wenang pada waktu pemanggilan fungsi.
Misalnya, Anda mungkin ingin menyingkat
height
danwidth
sebagaih
danw
di dalam definisi fungsi Anda, untuk membuatnya lebih pendek dan lebih bersih, sementara Anda masih ingin menyebutnya dengan nama lengkap untuk kejelasan:Fleksibilitas ini juga lebih berguna untuk pemrograman fungsional, di mana fungsi dapat diubah secara sewenang-wenang dengan nama param aslinya hilang.
sumber
Berasal dari Python, ini menyadap saya. Saya menulis pembungkus sederhana / Proxy untuk node yang akan menerima objek posisi dan kata kunci.
https://github.com/vinces1979/node-def/blob/master/README.md
sumber
f(x, opt)
manaopt
objek. Apakah itu membantu untuk menghindari atau membuat kesalahan (seperti yang disebabkan oleh kesalahan ejaan dan rasa sakit untuk mengingat nama kata kunci) tetap menjadi pertanyaan.kwargs
diksi satu per satu dan akhirnya menaikkanTypeError
jika ada kunci yang tidak diketahui yang tersisa). Andaf(x, opt)
solusi memungkinkan paraf
fungsi untuk melakukan sesuatu seperti di Python 2, tetapi Anda akan perlu untuk menangani semua nilai default sendiri.f(x, opt)
sudah berfungsi, sementara saya tidak melihat bagaimana ini membantu menjawab pertanyaan, di mana misalnya Anda ingin melakukan keduanyarequest(url)
danrequest({url: url})
itu tidak akan mungkin dilakukan dengan membuaturl
parameter hanya kata kunci.Berlawanan dengan apa yang umumnya diyakini, parameter bernama dapat diimplementasikan dalam JavaScript standar, old-school (hanya untuk parameter boolean) melalui konvensi pengkodean yang rapi dan sederhana, seperti yang ditunjukkan di bawah ini.
Peringatan:
Urutan argumen harus dipertahankan - tetapi polanya masih berguna, karena memperjelas argumen aktual mana yang dimaksudkan untuk parameter formal mana tanpa harus memahami fungsi tanda tangan atau menggunakan IDE.
Ini hanya berfungsi untuk boolean. Namun, saya yakin pola yang sama dapat dikembangkan untuk jenis lain menggunakan semantik jenis paksaan JavaScript.
sumber
height
menyebutkan nama terlepas dari urutan param.