Apa cara terbaik untuk kelebihan fungsi palsu di Javascript?
Saya tahu tidak mungkin untuk membebani fungsi dalam Javascript seperti pada bahasa lain. Jika saya membutuhkan fungsi dengan dua penggunaan foo(x)
dan foo(x,y,z)
yang merupakan cara terbaik / disukai:
- Menggunakan nama yang berbeda di tempat pertama
- Menggunakan argumen opsional seperti
y = y || 'default'
- Menggunakan sejumlah argumen
- Memeriksa jenis argumen
- Atau bagaimana?
javascript
overloading
hamdiakoguz
sumber
sumber
Jawaban:
Cara terbaik untuk melakukan overloading fungsi dengan parameter adalah tidak memeriksa panjang argumen atau jenisnya; memeriksa jenisnya hanya akan membuat kode Anda lambat dan Anda bersenang-senang dengan Array, nulls, Objects, dll.
Apa yang dilakukan sebagian besar pengembang adalah menempel pada objek sebagai argumen terakhir untuk metode mereka. Objek ini bisa menampung apa saja.
Maka Anda bisa mengatasinya tetap Anda inginkan dalam metode Anda. [Ganti, jika ada, dll.]
sumber
if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
arguments.length
tidak direkomendasikan? Juga, saya pernah ke sini sebelumnya dan membaca Apa yang dilakukan kebanyakan pengembang adalah ... , tapi saya yakin ini adalah satu-satunya tempat yang pernah saya lihat. Metode itu juga merusak gula sintaksis karena memiliki 'kelebihan'!Saya sering melakukan ini:
C #:
Setara JavaScript:
Contoh khusus ini sebenarnya lebih elegan dalam javascript daripada C #. Parameter yang tidak ditentukan adalah 'tidak terdefinisi' dalam javascript, yang dievaluasi menjadi false dalam pernyataan if. Namun, definisi fungsi tidak menyampaikan informasi bahwa p2 dan p3 adalah opsional. Jika Anda membutuhkan banyak kelebihan, jQuery telah memutuskan untuk menggunakan objek sebagai parameter, misalnya, jQuery.ajax (opsi). Saya setuju dengan mereka bahwa ini adalah pendekatan kelebihan muatan yang paling kuat dan dapat didokumentasikan, tetapi saya jarang membutuhkan lebih dari satu atau dua parameter opsional cepat.
EDIT: mengubah tes IF sesuai saran Ian
sumber
undefined
dalam JS, tidaknull
. Sebagai praktik terbaik, Anda tidak boleh mengatur apa pun untukundefined
, jadi itu seharusnya tidak menjadi masalah selama Anda mengubah tes Andap2 === undefined
.false
sebagai argumen terakhir maka itu tidak akan"false"
selesai sampai akhir, karenaif(p3)
tidak akan bercabang.typeof p2 === "undefined"
mungkin kebalikan dari apa yang Anda harapkan dalam contoh Anda, saya pikirtypeof p2 !== "undefined"
adalah apa yang Anda maksudkan. Juga, Bolehkah saya menyarankan untuk menggabungkan string, angka, dan boolean yang sebenarnya Anda lakukanp2 === "number"; p3 === "boolean"
===
dan!==
? Kenapa tidak pakai saja==
dan!=
?Tidak ada fungsi nyata kelebihan dalam JavaScript karena memungkinkan untuk melewati sejumlah parameter jenis apa pun. Anda harus memeriksa di dalam fungsi, berapa banyak argumen yang telah diajukan dan apa jenisnya.
sumber
Jawaban yang benar adalah TIDAK ADA OVERLOADING DI JAVASCRIPT.
Memeriksa / Mengalihkan di dalam fungsi tersebut tidak MENGATASI.
Konsep overloading: Dalam beberapa bahasa pemrograman, fungsi overloading atau overloading metode adalah kemampuan untuk membuat beberapa metode dengan nama yang sama dengan implementasi yang berbeda. Panggilan ke fungsi yang kelebihan beban akan menjalankan implementasi spesifik dari fungsi yang sesuai dengan konteks panggilan, memungkinkan satu panggilan fungsi untuk melakukan tugas yang berbeda tergantung pada konteksnya.
Sebagai contoh, doTask () dan doTask (objek O) adalah metode kelebihan beban. Untuk memanggil yang terakhir, sebuah objek harus dilewatkan sebagai parameter, sedangkan yang pertama tidak memerlukan parameter, dan dipanggil dengan bidang parameter kosong. Kesalahan umum adalah untuk menetapkan nilai default ke objek dalam metode kedua, yang akan menghasilkan kesalahan panggilan ambigu, karena kompiler tidak akan tahu yang mana dari dua metode yang digunakan.
https://en.wikipedia.org/wiki/Function_overloading
Semua implementasi yang disarankan bagus, tapi jujur saja, tidak ada implementasi asli untuk JavaScript.
sumber
Ada dua cara Anda bisa mendekati ini dengan lebih baik:
Lulus kamus (array asosiatif) jika Anda ingin memberikan banyak fleksibilitas
Ambil objek sebagai argumen dan gunakan pewarisan berbasis prototipe untuk menambah fleksibilitas.
sumber
Berikut adalah pendekatan yang memungkinkan overloading metode nyata menggunakan tipe parameter, yang ditunjukkan di bawah ini:
Edit (2018) : Karena ini ditulis pada tahun 2011, kecepatan panggilan metode langsung telah sangat meningkat sementara kecepatan metode kelebihan beban tidak.
Ini bukan pendekatan yang saya rekomendasikan, tetapi merupakan pemikiran yang bermanfaat untuk memikirkan bagaimana Anda dapat memecahkan masalah-masalah seperti ini.
Berikut adalah patokan dari berbagai pendekatan - https://jsperf.com/function-overloading . Ini menunjukkan bahwa kelebihan fungsi (memperhitungkan jenis) dapat sekitar 13 kali lebih lambat di Google Chrome V8 pada 16.0 (beta) .
Serta melewati objek (yaitu
{x: 0, y: 0}
), seseorang juga dapat mengambil pendekatan C saat yang tepat, penamaan metode yang sesuai. Misalnya, Vector.AddVector (vektor), Vector.AddIntegers (x, y, z, ...) dan Vector.AddArray (integerArray). Anda dapat melihat pustaka C, seperti OpenGL untuk penamaan inspirasi.Edit : Saya telah menambahkan patokan untuk meneruskan objek dan menguji objek menggunakan keduanya
'param' in arg
danarg.hasOwnProperty('param')
, dan fungsi kelebihan beban jauh lebih cepat daripada melewati objek dan memeriksa properti (setidaknya dalam patokan ini).Dari perspektif desain, fungsi kelebihan hanya valid atau logis jika parameter kelebihan sesuai dengan tindakan yang sama. Jadi masuk akal bahwa seharusnya ada metode mendasar yang hanya memusatkan perhatian pada perincian spesifik, jika tidak, itu mungkin mengindikasikan pilihan desain yang tidak tepat. Jadi kita juga bisa menyelesaikan penggunaan fungsi kelebihan dengan mengkonversi data ke objek masing-masing. Tentu saja orang harus mempertimbangkan ruang lingkup masalah karena tidak perlu membuat desain yang rumit jika niat Anda hanya untuk mencetak nama, tetapi untuk desain kerangka kerja dan perpustakaan pemikiran seperti itu dibenarkan.
Contoh saya berasal dari implementasi Rectangle - maka disebutkan Dimensi dan Titik. Mungkin Rectangle dapat menambahkan
GetRectangle()
metode keDimension
danPoint
prototipe, dan kemudian masalah kelebihan fungsi diurutkan. Dan bagaimana dengan primitif? Kita memiliki panjang argumen, yang sekarang merupakan tes yang valid karena objek memilikiGetRectangle()
metode.sumber
Cara terbaik sangat tergantung pada fungsi dan argumennya. Setiap pilihan Anda adalah ide bagus dalam situasi yang berbeda. Saya biasanya mencoba ini dalam urutan berikut sampai salah satu dari mereka berfungsi:
Menggunakan argumen opsional seperti y = y || 'default'. Ini nyaman jika Anda bisa melakukannya, tetapi mungkin tidak selalu berhasil secara praktis, misalnya ketika 0 / null / undefined akan menjadi argumen yang valid.
Menggunakan sejumlah argumen. Mirip dengan opsi terakhir tetapi dapat bekerja ketika # 1 tidak berfungsi.
Memeriksa jenis argumen. Ini dapat bekerja dalam beberapa kasus di mana jumlah argumennya sama. Jika Anda tidak dapat menentukan jenisnya dengan andal, Anda mungkin perlu menggunakan nama yang berbeda.
Menggunakan nama yang berbeda di tempat pertama. Anda mungkin perlu melakukan ini jika opsi lain tidak berfungsi, tidak praktis, atau untuk konsistensi dengan fungsi terkait lainnya.
sumber
Masalahnya adalah bahwa JavaScript TIDAK mendukung kelebihan metode secara bawaan. Jadi, jika ia melihat / mem-parsing dua atau lebih fungsi dengan nama yang sama, ia hanya akan mempertimbangkan fungsi yang didefinisikan terakhir dan menimpa yang sebelumnya.
Salah satu cara yang menurut saya cocok untuk sebagian besar kasus adalah sebagai berikut -
Katakanlah Anda memiliki metode
Alih-alih metode overloading yang tidak mungkin dilakukan dalam javascript, Anda dapat menentukan metode baru
dan kemudian memodifikasi fungsi 1 sebagai berikut -
Jika Anda memiliki banyak metode kelebihan seperti itu pertimbangkan untuk menggunakan
switch
bukan hanyaif-else
pernyataan.( lebih detail )
PS: Tautan di atas menuju ke blog pribadi saya yang memiliki detail tambahan.
sumber
Saya tidak yakin tentang praktik terbaik, tetapi inilah cara saya melakukannya:
sumber
Saya baru saja mencoba ini, mungkin itu sesuai dengan kebutuhan Anda. Bergantung pada jumlah argumen, Anda dapat mengakses fungsi yang berbeda. Anda menginisialisasi saat pertama kali Anda menyebutnya. Dan peta fungsi disembunyikan di penutupan.
Menguji.
sumber
Karena JavaScript tidak memiliki fungsi, objek opsi overload dapat digunakan sebagai gantinya. Jika ada satu atau dua argumen yang diperlukan, lebih baik memisahkannya dari objek opsi. Berikut adalah contoh tentang cara menggunakan objek opsi dan nilai yang dihuni ke nilai default jika nilai tidak diteruskan dalam objek opsi.
di sini adalah contoh tentang cara menggunakan objek opsi
sumber
Tidak ada cara untuk berfungsi kelebihan dalam javascript. Jadi, saya sarankan seperti berikut dengan
typeof()
metode alih-alih beberapa fungsi ke pemuatan berlebih palsu.Semoga berhasil!
sumber
var type = typeof param; if (type === 'string') ...
PENGANTAR
Sejauh ini membaca begitu banyak jawaban akan membuat orang sakit kepala. Siapa pun yang ingin tahu konsepnya perlu mengetahui prasyarat berikut .
Function overloading Definition
,Function Length property
,Function argument property
Function overloading
dalam bentuknya yang paling sederhana berarti bahwa suatu fungsi melakukan tugas yang berbeda berdasarkan jumlah argumen yang diteruskan kepadanya. Khususnya TASK1, TASK2 dan TASK3 disorot di bawah ini dan dilakukan berdasarkan jumlaharguments
yang diteruskan ke fungsi yang samafooYo
.CATATAN - JS tidak memberikan kemampuan kelebihan fungsi yang bawaan.
Alternatif
John E Resig (pembuat JS) telah menunjukkan alternatif yang menggunakan prasyarat di atas untuk mencapai kemampuan untuk mengimplementasikan fungsi overloading.
Kode di bawah ini menggunakan pendekatan langsung tetapi naif dengan menggunakan
if-else
atauswitch
pernyataan.argument-length
properti.Teknik lain jauh lebih bersih dan dinamis. Sorotan teknik ini adalah
addMethod
fungsi generik.kita mendefinisikan fungsi
addMethod
yang digunakan untuk menambahkan fungsi yang berbeda ke objek dengan nama yang sama tetapi fungsi yang berbeda .di bawah
addMethod
fungsi menerima tiga nama objek paramsobject
, nama fungsiname
dan fungsi yang ingin kita panggilfn
.addMethod
definisivar old
menyimpan referensi ke yang sebelumnyafunction
disimpan dengan bantuan penutupan - gelembung pelindung.addMethod
menambahkan tiga fungsi yang ketika dipanggil digunakanninja.whatever(x)
dengan jumlah argumenx
yang bisa berupa apa saja yaitu kosong atau satu atau lebih dari satu memanggil fungsi yang berbeda seperti yang didefinisikan saat memanfaatkanaddMethod
fungsi.sumber
Cara lain untuk mendekati ini adalah dengan menggunakan variabel khusus: argumen , ini adalah implementasi:
sehingga Anda dapat mengubah kode ini menjadi:
sumber
lihat ini. Itu sangat keren. http://ejohn.org/blog/javascript-method-overloading/ Trik Javascript untuk memungkinkan Anda melakukan panggilan seperti ini:
sumber
Func(new Point())
danFunc(new Rectangle())
akan menjalankan fungsi yang berbeda. Tetapi saya harus menunjukkan bahwa ini adalah hack kotor, karena metode overloading sebenarnya adalah tugas kompilasi waktu tidak berjalan waktu.Fungsi overloading di Javascript:
Function overloading adalah kemampuan bahasa pemrograman untuk membuat banyak fungsi dengan nama yang sama dengan implementasi yang berbeda. ketika fungsi kelebihan beban dipanggil akan menjalankan fungsi implementasi spesifik dari fungsi yang sesuai dengan konteks panggilan. Konteks ini biasanya jumlah argumen yang diterima, dan memungkinkan satu pemanggilan fungsi untuk berperilaku berbeda tergantung pada konteks.
Javascript tidak memiliki kelebihan fungsi bawaan. Namun, perilaku ini dapat ditiru dengan banyak cara. Inilah yang sederhana dan nyaman:
Dalam skenario di mana Anda tidak tahu berapa banyak argumen yang akan Anda dapatkan, Anda dapat menggunakan operator lainnya yang terdiri dari tiga titik
...
. Ini akan mengubah sisa argumen menjadi sebuah array. Waspadalah terhadap kompatibilitas browser. Berikut ini sebuah contoh:sumber
Karena posting ini sudah mengandung banyak solusi yang berbeda, saya pikir saya memposting yang lain.
ini dapat digunakan seperti yang ditunjukkan di bawah ini:
Solusi ini tidak sempurna tetapi saya hanya ingin menunjukkan bagaimana itu bisa dilakukan.
sumber
Anda dapat menggunakan 'addMethod' dari John Resig. Dengan metode ini Anda dapat "membebani" metode berdasarkan jumlah argumen.
Saya juga telah membuat alternatif untuk metode ini yang menggunakan caching untuk menyimpan variasi fungsi. Perbedaannya dijelaskan di sini
sumber
Pola Penerusan => praktik terbaik tentang JS overloading
Teruskan ke fungsi lain yang namanya dibangun dari poin ke-3 & ke-4:
Aplikasi pada kasus Anda:
Sampel Kompleks lainnya:
sumber
Function Overloading melalui Dynamic Polymorphism dalam 100 baris JS
Ini dari tubuh yang lebih besar dari kode yang meliputi
isFn
,isArr
, dll jenis fungsi pemeriksaan. Versi VanillaJS di bawah ini telah dikerjakan ulang untuk menghapus semua dependensi eksternal, namun Anda harus menentukan fungsi memeriksa jenis Anda sendiri untuk digunakan dalam.add()
panggilan.Catatan: Ini adalah fungsi self-executing (sehingga kita dapat memiliki lingkup penutupan / tertutup), karenanya tugas untuk
window.overload
daripadafunction overload() {...}
.Pemakaian:
Penelepon mendefinisikan fungsi kelebihannya dengan menetapkan variabel untuk kembalinya
overload()
. Berkat rantai, kelebihan beban tambahan dapat didefinisikan secara seri:Argumen opsional tunggal untuk
overload()
menetapkan fungsi "default" untuk dipanggil jika tanda tangan tidak dapat diidentifikasi. Argumen untuk.add()
adalah:fn
:function
mendefinisikan kelebihan;a_vArgumentTests
:Array
offunction
s mendefinisikan tes untuk dijalankan padaarguments
. Masing-masingfunction
menerima satu argumen dan mengembalikantrue
argumen Anda jika argumen itu valid;sAlias
(Opsional):string
mendefinisikan alias untuk secara langsung mengakses fungsi overload (fn
), mis.myOverloadedFn.noArgs()
Akan memanggil fungsi itu secara langsung, menghindari tes polimorfisme dinamis dari argumen.Implementasi ini sebenarnya memungkinkan lebih dari sekedar kelebihan fungsi tradisional karena
a_vArgumentTests
argumen kedua.add()
dalam praktiknya mendefinisikan tipe kustom. Jadi, Anda bisa membuat gerbang argumen tidak hanya berdasarkan jenis, tetapi pada rentang, nilai, atau koleksi nilai!Jika Anda melihat melalui 145 baris kode untuk
overload()
Anda akan melihat bahwa setiap tanda tangan dikategorikan berdasarkan jumlah yangarguments
diteruskan ke sana. Ini dilakukan agar kami membatasi jumlah tes yang kami jalankan. Saya juga melacak jumlah panggilan. Dengan beberapa kode tambahan, array fungsi yang kelebihan beban dapat disortir ulang sehingga fungsi yang lebih umum diuji terlebih dahulu, kembali menambahkan beberapa ukuran peningkatan kinerja.Sekarang, ada beberapa peringatan ... Karena Javascript diketik secara longgar, Anda harus berhati-hati dengan Anda
vArgumentTests
karenainteger
dapat divalidasi sebagaifloat
, dll.Versi JSCompress.com (1114 byte, 744 byte g-zip):
sumber
Anda sekarang dapat melakukan fungsi overloading di ECMAScript 2018 tanpa polyfill, memeriksa var length / type, dll., Cukup gunakan sintaks spread .
Apa itu sintaksis penyebaran?
Catatan: menyebar sintaks dalam objek literal tidak berfungsi di Edge dan IE dan itu adalah fitur eksperimental. lihat kompatibilitas browser
sumber
Hal seperti ini dapat dilakukan untuk fungsi yang berlebihan.
Sumber
sumber
Ini adalah pertanyaan lama tetapi satu yang saya pikir perlu entri lain (walaupun saya ragu ada yang akan membacanya). Penggunaan Ekspresi Fungsi Segera Diminta (IIFE) dapat digunakan bersama dengan fungsi penutupan dan inline untuk memungkinkan kelebihan fungsi. Pertimbangkan contoh berikut (dibuat-buat):
Singkatnya, penggunaan IIFE menciptakan ruang lingkup lokal, memungkinkan kita untuk mendefinisikan variabel pribadi
old
untuk menyimpan referensi ke definisi awal fungsifoo
. Fungsi ini kemudian mengembalikan fungsi inlinenewFoo
yang mencatat konten dari kedua argumen jika dilewatkan tepat dua argumena
danb
atau memanggilold
fungsi jikaarguments.length !== 2
. Pola ini dapat diulang beberapa kali untuk memberikan satu variabel dengan beberapa definisi fungsional yang berbeda.sumber
Saya ingin membagikan contoh berguna tentang pendekatan seperti kelebihan beban.
Penggunaan: Hapus (); // Membersihkan semua dokumen
Bersihkan (myDiv); // Membersihkan panel yang direferensikan oleh myDiv
sumber
JavaScript adalah bahasa yang tidak diketik, dan saya hanya berpikir itu masuk akal untuk membebani metode / fungsi sehubungan dengan jumlah params. Oleh karena itu, saya akan merekomendasikan untuk memeriksa apakah parameternya telah ditentukan:
sumber
Pada Juli 2017, berikut ini adalah teknik umum. Perhatikan bahwa kami juga dapat melakukan pemeriksaan tipe dalam fungsi.
sumber
Untuk kasus penggunaan Anda, ini adalah bagaimana saya akan mengatasinya
ES6
(karena ini sudah akhir tahun 2017):Anda dapat dengan jelas mengadaptasi ini untuk bekerja dengan sejumlah parameter dan hanya mengubah pernyataan bersyarat Anda sesuai.
sumber
tidak ada overloading aktual di JS, toh kita masih bisa mensimulasikan metode overloading dalam beberapa cara:
metode # 1: gunakan objek
metode # 2: gunakan parameter sisa (sebaran)
Metode # 3: gunakan undefined
metode # 4: memeriksa jenis
sumber
Meskipun parameter Default tidak kelebihan beban, ini mungkin bisa menyelesaikan beberapa masalah yang dihadapi pengembang di area ini. Input benar-benar ditentukan oleh pesanan, Anda tidak dapat memesan ulang seperti yang Anda inginkan seperti pada overloading klasik:
Hasil dalam (untuk tahun 2020):
Info lebih lanjut: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
sumber
Opsi pertama benar-benar layak mendapat perhatian karena itu adalah hal yang saya buat dalam pengaturan kode yang cukup kompleks. Jadi, jawabanku adalah
Dengan sedikit tapi petunjuk penting, nama akan terlihat berbeda untuk komputer, tetapi tidak untuk Anda. Nama kelebihan fungsi seperti: func, func1, func2.
sumber