Saya perlu membuat fungsi yang hanya dapat dijalankan sekali, setiap kali setelah yang pertama tidak akan dijalankan. Saya tahu dari C ++ dan Java tentang variabel statis yang dapat melakukan pekerjaan itu tetapi saya ingin tahu apakah ada cara yang lebih elegan untuk melakukan ini?
javascript
function
design-patterns
vlio20.dll
sumber
sumber
Jawaban:
Jika dengan "tidak akan dieksekusi" yang Anda maksud "tidak akan melakukan apa-apa saat dipanggil lebih dari sekali", Anda dapat membuat penutupan:
Sebagai jawaban atas komentar @Vladloffe (sekarang dihapus): Dengan variabel global, kode lain dapat menyetel ulang nilai dari tanda "dieksekusi" (apa pun nama yang Anda pilih). Dengan penutupan, kode lain tidak memiliki cara untuk melakukan itu, baik secara tidak sengaja atau sengaja.
Seperti jawaban lain yang ditunjukkan di sini, beberapa pustaka (seperti Underscore dan Ramda ) memiliki fungsi utilitas kecil (biasanya bernama
once()
[*] ) yang menerima fungsi sebagai argumen dan mengembalikan fungsi lain yang memanggil fungsi yang disediakan tepat sekali, terlepas dari bagaimana caranya berkali-kali fungsi yang dikembalikan dipanggil. Fungsi yang dikembalikan juga menyimpan nilai yang pertama kali dikembalikan oleh fungsi yang disediakan dan mengembalikannya pada panggilan berikutnya.Namun, jika Anda tidak menggunakan pustaka pihak ketiga seperti itu, tetapi masih menginginkan fungsi utilitas seperti itu (daripada solusi nonce yang saya tawarkan di atas), cukup mudah untuk diterapkan. Versi terbaik yang pernah saya lihat adalah yang ini diposting oleh David Walsh :
Saya akan cenderung untuk berubah
fn = null;
menjadifn = context = null;
. Tidak ada alasan bagi penutupan untuk mempertahankan referensi kecontext
sekalifn
telah dipanggil.[*] Namun, ketahuilah, bahwa pustaka lain, seperti ekstensi Drupal ke jQuery ini , mungkin memiliki fungsi bernama
once()
yang melakukan sesuatu yang sangat berbeda.sumber
if
ekspresi pengujian pernyataan), JavaScript mengharapkan salah satu nilaitrue
ataufalse
dan aliran program bereaksi sesuai dengan nilai yang ditemukan saat ekspresi dievaluasi. Operator bersyarat seperti==
selalu mengevaluasi ke nilai boolean. Variabel juga dapat menampung salah satutrue
ataufalse
. (Untuk info lebih lanjut, lihat dokumentasi tentang boolean , truthy , and falsey .)Gantilah dengan fungsi NOOP (tanpa operasi) yang dapat digunakan kembali .
sumber
setInterval(foo, 1000)
- dan ini sudah tidak berfungsi lagi. Anda baru saja menimpa referensi dalam lingkup saat ini.invalidate
fungsi yang bekerja dengansetInterval
dll,:. Jsbin.com/vicipar/1/edit?js,consoleArahkan ke fungsi kosong setelah dipanggil:
Atau, seperti:
sumber
setInterval()
) maka referensi akan mengulangi fungsionalitas asli saat dipanggil.UnderscoreJs memiliki fungsi yang melakukan itu, underscorejs.org/#once
sumber
once
menerima argumen. Anda dapat melakukansquareo = _.once(square); console.log(squareo(1)); console.log(squareo(2));
dan mendapatkan1
kedua panggilan kesquareo
. Apakah saya memahami ini dengan benar?_.once
metode tersebut. Lihat jsfiddle.net/631tgc5f/1_
; Saya tidak akan merekomendasikan bergantung pada seluruh perpustakaan untuk kode sekecil itu.Berbicara tentang variabel statis, ini sedikit mirip dengan varian penutupan:
Anda kemudian dapat mengatur ulang suatu fungsi jika Anda ingin:
sumber
sumber
Anda bisa saja memiliki fungsi "menghapus dirinya sendiri"
Tapi ini mungkin bukan jawaban terbaik jika Anda tidak ingin salah menelan.
Anda juga bisa melakukan ini:
Saya membutuhkannya untuk bekerja seperti smart pointer, jika tidak ada elemen dari tipe A maka dapat dijalankan, jika ada satu atau lebih elemen A, fungsinya tidak dapat dijalankan.
sumber
Once
diteruskan sebagai panggilan balik (mis.,setInterval(Once, 100)
). Fungsi asli akan terus dipanggil.coba ini
sumber
Dari beberapa pria bernama Crockford ... :)
sumber
TypeError: Cannot read property 'apply' of null
bagus. Itulah yang Anda dapatkan saat kedua kali Anda memanggil fungsi yang dikembalikan.Reusable
invalidate
fungsi yang bekerja dengansetInterval
:Cobalah di JSBin: https://jsbin.com/vicipar/edit?js,console
Variasi jawaban dari Bunyk
sumber
Berikut adalah contoh JSFiddle - http://jsfiddle.net/6yL6t/
Dan kodenya:
Anda bisa melakukan:
Dan itu akan berjalan hanya sekali :)
sumber
Pengaturan awal:
sumber
Jika Anda menggunakan Node.js atau menulis JavaScript dengan browserify, pertimbangkan modul npm "Once" :
sumber
Jika Anda ingin dapat menggunakan kembali fungsi tersebut di masa mendatang, maka ini berfungsi dengan baik berdasarkan kode ed Hopp di atas (Saya menyadari bahwa pertanyaan asli tidak memerlukan fitur tambahan ini!):
Outputnya terlihat seperti:
sumber
dekorator sederhana yang mudah ditulis saat Anda membutuhkan
menggunakan:
sumber
Mencoba menggunakan fungsi garis bawah "sekali":
http://underscorejs.org/#once
sumber
sumber
Jika Anda menggunakan Ramda, Anda dapat menggunakan fungsi "sekali" .
Kutipan dari dokumentasi:
sumber
buat sesederhana mungkin
Anda bisa lihat hasilnya
sumber
this
sebagai penggantiwindow
JQuery memungkinkan untuk memanggil fungsi hanya sekali menggunakan metode one () :
Implementasi menggunakan metode JQuery pada () :
Implementasi menggunakan JS asli:
sumber
sumber
Yang ini berguna untuk mencegah loop tak terbatas (menggunakan jQuery):
Jika Anda khawatir tentang polusi namespace, gantikan string acak yang panjang untuk "doIt".
sumber
Ini membantu mencegah eksekusi yang lengket
sumber