Apa cara tercepat untuk mengkloning fungsi di JavaScript (dengan atau tanpa propertinya)?
Dua opsi yang muncul di benak adalah eval(func.toString())
dan function() { return func.apply(..) }
. Tapi saya khawatir kinerja eval dan wrapping akan memperburuk stack dan mungkin akan menurunkan performa jika diterapkan banyak atau diterapkan pada yang sudah dibungkus.
new Function(args, body)
terlihat bagus, tapi bagaimana tepatnya saya bisa membagi fungsi yang ada menjadi args dan body tanpa parser JS di JS?
Terima kasih sebelumnya.
Pembaruan: Yang saya maksud adalah bisa melakukan
var funcB = funcA.clone(); // where clone() is my extension
funcB.newField = {...}; // without affecting funcA
javascript
function
Andrey Shchekin
sumber
sumber
Jawaban:
coba ini:
sumber
Berikut adalah jawaban yang diperbarui
Namun
.bind
adalah fitur JavaScript modern (> = iE9) (dengan solusi kompatibilitas dari MDN )Catatan
Ini tidak mengkloning fungsi objek tambahan yang melekat sifat , termasuk para prototipe properti. Penghargaan untuk @jchook
Fungsi baru ini variabel terjebak dengan argumen yang diberikan pada bind (), bahkan pada fungsi baru berlaku () panggilan. Penghargaan untuk @Kevin
sumber
newFunc
TIDAK akan memiliki prototipe sendiri untuknew newFunc
instance, sementaraoldFunc
akan.var f = function() { console.log('hello ' + this.name) }
ketika terikat untuk{name: 'Bob'}
mencetak 'halo Bob'.f.apply({name: 'Sam'})
juga akan mencetak 'halo Bob', mengabaikan objek 'ini'.function () { [native code] }
alih - alih konten fungsi penuh.Ini adalah versi jawaban Jared yang sedikit lebih baik. Yang ini tidak akan berakhir dengan fungsi yang sangat bertingkat semakin Anda mengkloning. Itu selalu menyebut aslinya.
Juga, sebagai tanggapan atas jawaban terbaru yang diberikan oleh pico.creator, perlu dicatat bahwa
bind()
fungsi yang ditambahkan dalam Javascript 1.8.5 memiliki masalah yang sama dengan jawaban Jared - ini akan terus bersarang menyebabkan fungsi yang lebih lambat dan lambat setiap kali digunakan.sumber
Karena penasaran tetapi masih tidak dapat menemukan jawaban untuk topik kinerja dari pertanyaan di atas, saya menulis inti dari nodejs ini untuk menguji kinerja dan keandalan semua solusi yang disajikan (dan diberi skor).
Saya telah membandingkan waktu dinding pembuatan fungsi klon dan eksekusi klon. Hasil bersama dengan kesalahan pernyataan disertakan dalam komentar inti.
Ditambah dua sen saya (berdasarkan saran penulis):
clone0 sen (lebih cepat tapi lebih jelek):
clone4 cent (lebih lambat tetapi bagi mereka yang tidak menyukai eval () untuk tujuan yang hanya diketahui oleh mereka dan leluhur mereka):
Adapun kinerjanya, jika eval / Fungsi baru lebih lambat dari solusi pembungkus (dan itu benar-benar tergantung pada ukuran tubuh fungsi), itu memberi Anda klon fungsi telanjang (dan maksud saya klon dangkal sejati dengan properti tetapi status tidak dibagikan) tanpa fuzz yang tidak perlu dengan properti tersembunyi, fungsi pembungkus, dan masalah dengan tumpukan.
Selain itu, selalu ada satu faktor penting yang perlu Anda pertimbangkan: semakin sedikit kode, semakin sedikit tempat untuk kesalahan.
Kelemahan dari penggunaan fungsi eval / baru adalah bahwa fungsi klon dan asli akan beroperasi dalam cakupan yang berbeda. Ini tidak akan berfungsi dengan baik dengan fungsi yang menggunakan variabel cakupan. Solusi yang menggunakan pembungkusan seperti ikatan tidak bergantung pada cakupan.
sumber
Object.assign(newfun.prototype, this.prototype);
sebelum pernyataan return (versi bersih), metode Anda adalah jawaban terbaik.Cukup mengasyikkan untuk membuat metode ini berfungsi, jadi metode ini membuat klon dari suatu fungsi menggunakan panggilan Fungsi.
Beberapa batasan tentang closure dijelaskan di Referensi Fungsi MDN
Nikmati.
sumber
Singkat dan sederhana:
sumber
sumber
sumber
originalFunction
, tetapi tidak akan benar-benar mengeksekusinya ketika Anda menjalankanclonedFunction
, yang tidak terduga.Jawaban ini untuk orang-orang yang melihat penggandaan suatu fungsi sebagai jawaban untuk penggunaan yang diinginkan, tetapi banyak yang sebenarnya tidak perlu mengkloning suatu fungsi, karena yang sebenarnya mereka inginkan hanyalah dapat melampirkan properti yang berbeda ke fungsi yang sama, tetapi hanya nyatakan fungsi itu satu kali.
Lakukan ini dengan membuat fungsi pembuatan fungsi:
Ini tidak persis sama seperti yang Anda uraikan, namun, ini tergantung pada bagaimana Anda ingin menggunakan fungsi yang ingin Anda klon. Ini juga menggunakan lebih banyak memori karena sebenarnya membuat beberapa salinan fungsi, satu kali per pemanggilan. Namun, teknik ini dapat menyelesaikan kasus penggunaan beberapa orang tanpa memerlukan
clone
fungsi yang rumit .sumber
Hanya ingin tahu - mengapa Anda ingin mengkloning suatu fungsi saat Anda memiliki prototipe DAN dapat menyetel cakupan panggilan fungsi ke apa pun yang Anda inginkan?
sumber
Jika Anda ingin membuat klon menggunakan konstruktor Fungsi, sesuatu seperti ini seharusnya berfungsi:
Tes sederhana:
Klon ini akan kehilangan nama dan ruang lingkupnya untuk variabel tertutup apa pun.
sumber
Saya telah memaksakan jawaban Jared dengan cara saya sendiri:
1) sekarang mendukung kloning konstruktor (dapat memanggil dengan yang baru); dalam hal ini hanya membutuhkan 10 argumen (Anda dapat memvariasikannya) - karena ketidakmungkinan meneruskan semua argumen dalam konstruktor asli
2) semuanya dalam penutupan yang benar
sumber
arguments[0], arguments[1] /*[...]*/
mengapa Anda tidak menggunakan saja...arguments
? 1) Tidak ada ketergantungan mengenai jumlah argumen (di sini terbatas pada 10) 2) lebih pendekMeskipun saya tidak akan merekomendasikan penggunaan ini, saya pikir itu akan menjadi tantangan kecil yang menarik untuk menghasilkan klon yang lebih tepat dengan mengambil beberapa praktik yang tampaknya terbaik dan memperbaikinya sedikit. Berikut hasil log:
sumber
Fungsi klon ini:
Perhatikan bahwa versi ini hanya melakukan penyalinan dangkal. Jika fungsi Anda memiliki objek sebagai properti, referensi ke objek asli dipertahankan (perilaku yang sama seperti Object spread atau Object.assign). Ini berarti bahwa mengubah properti dalam di fungsi kloning akan memengaruhi objek yang direferensikan di fungsi aslinya!
sumber