mata teras
- penutupan JavaScript adalah fungsi yang boleh mengakses pembolehubah skop induk mereka.
- Fungsi panggil balik adalah fungsi yang diluluskan sebagai parameter kepada fungsi lain, yang kemudian dilaksanakan dalam fungsi luaran, menyediakan cara untuk melambatkan pelaksanaan atau mengekalkan perintah operasi tak segerak.
- Melaksanakan Ekspresi Fungsi Sekarang (Iife) adalah fungsi yang dilaksanakan dengan segera selepas definisi untuk melindungi skop pembolehubah dan mencegah pencemaran skop global.
- Penutupan boleh membaca dan mengemas kini pembolehubah yang disimpan dalam skop mereka, dan kemas kini ini dapat dilihat oleh sebarang penutupan yang mengakses pembolehubah ini, yang membuktikan bahawa penutupan kedai merujuk kepada pembolehubah, dan bukan nilai.
- Menggunakan IIFE membantu membuat skop peribadi dalam fungsi, dengan itu menguruskan pembolehubah dengan lebih baik dan menghalang akses luaran ke pembolehubah ini.
- Gabungan konsep -konsep ini (penutupan, fungsi panggil balik, dan IIFE) menyediakan alat yang berkuasa untuk menulis kod JavaScript ringkas, cekap dan selamat untuk merangkum fungsi dan mengelakkan pencemaran skop global.
Penutup
Dalam JavaScript, penutupan adalah sebarang fungsi yang mengekalkan rujukan kepada pemboleh ubah skop induknya, walaupun fungsi induk telah kembali. Sebenarnya, sebarang fungsi boleh dianggap sebagai penutupan, kerana seperti yang kita pelajari dalam bahagian Skop Variabel dari bahagian pertama tutorial ini, fungsi boleh dirujuk atau diakses:
Sebarang pembolehubah dan parameter dalam skop fungsi sendiri
- Sebarang pembolehubah dan parameter fungsi luaran (induk)
- Sebarang pemboleh ubah dalam skop global
- jadi anda mungkin telah menggunakan penutupan tanpa mengetahui. Tetapi matlamat kami bukan hanya untuk menggunakannya -tetapi untuk memahami mereka. Jika kita tidak faham bagaimana mereka berfungsi, kita tidak boleh menggunakannya dengan betul. Untuk melakukan ini, kami memecahkan definisi penutupan di atas ke tiga perkara utama yang mudah difahami.
Point 1: Anda boleh merujuk kepada pembolehubah yang ditakrifkan di luar fungsi semasa.
Dalam contoh kod ini, fungsi merujuk kepada parameter pembolehubah dan
fungsi yang tertutup (induk)function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } printLocation(); } setLocation("Paris"); // 输出:You are in Paris, France. Akibatnya, apabila
dipanggil, printLocation()
berjaya mengeluarkan "anda berada di Paris, Perancis" menggunakan bekas pembolehubah dan parameter. setLocation()
country
Point 2: city
Fungsi dalaman boleh merujuk kepada pembolehubah yang ditakrifkan dalam fungsi luaran walaupun selepas fungsi luaran pulangan. setLocation()
printLocation()
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } printLocation(); } setLocation("Paris"); // 输出:You are in Paris, France
Ini hampir sama dengan contoh pertama, kecuali kali ini printLocation()
kembali dalam di luar fungsi setLocation()
, dan bukannya memanggil segera. Oleh itu, nilai currentLocation
adalah fungsi dalaman printLocation()
.
Jika kita mengingatkan seperti ini currentLocation
- alert(currentLocation);
- kita akan mendapat output berikut:
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } return printLocation; } var currentLocation = setLocation("Paris"); currentLocation(); // 输出:You are in Paris, France
seperti yang telah kita lihat, printLocation()
dilaksanakan di luar skop leksikalnya. setLocation()
nampaknya hilang, tetapi printLocation()
masih boleh mengakses dan "ingat" pembolehubahnya (country
) dan parameter (city
).
Penutupan (fungsi dalaman) dapat mengingati skop di sekelilingnya (fungsi luaran) walaupun ia dilaksanakan di luar skop leksikalnya. Oleh itu, anda boleh memanggilnya pada bila -bila masa dalam program anda.
Point 3: fungsi dalaman menyimpan pembolehubah yang berfungsi luaran dengan rujukan, dan bukannya dengan nilai.
function printLocation () { console.log("You are in " + city + ", " + country); }
di sini cityLocation()
Mengembalikan objek yang mengandungi dua penutupan- get()
dan set()
-berkali merujuk kepada pembolehubah luaran city
. get()
Dapatkan nilai semasa city
dan set()
mengemas kini. Apabila panggilan kedua myLocation.get()
, ia mengeluarkan nilai terkini (semasa) city
- "Sydney" - bukannya "Paris" lalai.
daripada menyalin nilainya. Ini adalah titik yang sangat penting, kerana tidak mengetahui ini boleh membawa kepada beberapa kesilapan logik yang sukar dicari-seperti yang akan kita lihat dalam seksyen "melaksanakan ekspresi fungsi segera (Iife)". Ciri menarik penutupan ialah pembolehubah dalam penutupan secara automatik tersembunyi. Penutupan menyimpan data dalam pembolehubah tertutup tanpa menyediakan cara untuk mengaksesnya secara langsung. Satu -satunya cara untuk mengubah pembolehubah ini adalah untuk mengaksesnya secara tidak langsung. Sebagai contoh, dalam coretan kod terakhir, kita melihat bahawa kita hanya boleh secara tidak langsung mengubah suai pembolehubah
dengan menggunakan penutupan dan get()
. set()
city
kita boleh menggunakan tingkah laku ini untuk menyimpan data peribadi dalam objek. Daripada menyimpan data sebagai sifat objek, simpannya sebagai pembolehubah dalam pembina dan kemudian gunakan penutupan sebagai cara untuk merujuk pembolehubah tersebut.
Seperti yang anda lihat, tidak ada yang misteri atau mendalam di sekitar penutupan -hanya tiga mata mudah untuk diingat.
Fungsi Callback
Dalam JavaScript, fungsi adalah warga kelas pertama. Salah satu akibat dari fakta ini ialah fungsi boleh diluluskan sebagai hujah kepada fungsi lain atau dikembalikan oleh fungsi lain.
Fungsi yang mengambil fungsi lain sebagai parameter atau fungsi pulangan kerana hasilnya dipanggil fungsi pesanan lebih tinggi, dan fungsi yang diluluskan sebagai parameter dipanggil fungsi panggil balik. Ia dipanggil "panggilan balik" kerana pada satu ketika, ia akan menjadi "panggil balik" dengan fungsi pesanan yang lebih tinggi.
Fungsi panggil balik mempunyai banyak kegunaan harian. Salah satu daripada mereka adalah apabila kita menggunakan kaedah setTimeout()
dan setInterval()
objek tetingkap pelayar - kaedah ini menerima dan melaksanakan fungsi panggilan balik:
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } printLocation(); } setLocation("Paris"); // 输出:You are in Paris, France
Satu lagi contoh ialah apabila kita melampirkan pendengar acara ke elemen pada halaman. Dengan melakukan ini, kami sebenarnya memberikan penunjuk kepada fungsi panggil balik, yang akan dipanggil apabila peristiwa berlaku.
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } return printLocation; } var currentLocation = setLocation("Paris"); currentLocation(); // 输出:You are in Paris, France
Cara paling mudah untuk memahami bagaimana fungsi pesanan dan fungsi panggil balik yang lebih tinggi berfungsi adalah untuk mewujudkan fungsi pesanan tinggi dan fungsi panggilan balik anda sendiri. Jadi, mari buat sekarang:
function printLocation () { console.log("You are in " + city + ", " + country); }
di sini kita membuat fungsi fullName()
, yang menerima tiga parameter - dua untuk nama pertama dan terakhir, dan satu untuk fungsi panggilan balik. Kemudian, selepas pernyataan console.log()
, kami meletakkan panggilan fungsi yang akan mencetuskan fungsi panggil balik sebenar -fungsi fullName()
yang ditakrifkan di bawah greeting()
. Akhirnya, kami memanggil fullName()
di mana greeting()
diluluskan sebagai pemboleh ubah- tanpa kurungan -memberikannya kita tidak mahu ia dilaksanakan dengan segera, tetapi hanya mahu menunjuknya untuk kegunaan kemudian oleh fullName()
.
Kami melewati definisi fungsi, bukan fungsi panggilan. Ini menghalang fungsi panggil balik daripada dilaksanakan dengan serta -merta, yang tidak konsisten dengan falsafah di sebalik fungsi panggilan balik. Diluluskan sebagai definisi fungsi, mereka boleh dilaksanakan pada bila -bila masa dan pada bila -bila masa dalam fungsi yang mengandungi. Selain itu, kerana fungsi panggil balik berkelakuan seperti mereka sebenarnya diletakkan di dalam fungsi, mereka sebenarnya menutup: mereka boleh mengakses pembolehubah dan parameter yang mengandungi fungsi, dan juga mengakses pembolehubah dalam skop global.
Fungsi panggil balik boleh menjadi fungsi yang ada (seperti yang ditunjukkan dalam contoh sebelumnya) atau fungsi tanpa nama.
function cityLocation() { var city = "Paris"; return { get: function() { console.log(city); }, set: function(newCity) { city = newCity; } }; } var myLocation = cityLocation(); myLocation.get(); // 输出:Paris myLocation.set('Sydney'); myLocation.get(); // 输出:SydneyFungsi panggil balik digunakan secara meluas di perpustakaan JavaScript untuk menyediakan fleksibiliti dan kebolehgunaan semula. Mereka membenarkan penyesuaian mudah dan/atau lanjutan kaedah perpustakaan. Di samping itu, kod itu lebih mudah untuk mengekalkan dan lebih ringkas dan mudah dibaca. Fungsi panggil balik berguna apabila anda perlu menukar corak kod pendua yang tidak perlu menjadi lebih banyak fungsi abstrak/generik.
Katakan kita memerlukan dua fungsi - satu yang mencetak maklumat artikel yang diterbitkan dan yang lain yang mencetak maklumat mesej yang dihantar. Kami mencipta mereka, tetapi kami perhatikan bahawa sebahagian daripada logik kami diulang dalam kedua -dua fungsi. Kami tahu bahawa mempunyai kod yang sama di satu tempat tidak perlu dan sukar untuk dijaga. Jadi, apakah penyelesaiannya? Mari kita gambarkannya dalam contoh seterusnya:
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } printLocation(); } setLocation("Paris"); // 输出:You are in Paris, France
Apa yang kita lakukan di sini adalah meletakkan corak kod pendua (console.log(item)
dan var date = new Date()
) ke dalam fungsi umum yang berasingan (publish()
) dan hanya menyimpan data khusus dalam fungsi lain - fungsi ini kini menjadi fungsi panggilan balik. Dengan cara ini, menggunakan fungsi yang sama, kita boleh mencetak maklumat yang relevan mengenai pelbagai perkara yang berkaitan - mesej, artikel, buku, majalah, dll. Satu -satunya perkara yang perlu anda lakukan ialah membuat fungsi panggil balik khas untuk setiap jenis dan lulus sebagai hujah kepada fungsi publish()
.
Jalankan ekspresi fungsi dengan segera (iife)
Jalankan ekspresi fungsi dengan segera, atau Iife (disebut "ify"), adalah ungkapan fungsi (dinamakan atau tanpa nama) yang dilaksanakan dengan segera selepas ia dibuat.
Terdapat dua varian sintaks yang sedikit berbeza dalam mod ini:
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } return printLocation; } var currentLocation = setLocation("Paris"); currentLocation(); // 输出:You are in Paris, France
Untuk menukar fungsi biasa ke Iife, anda perlu melakukan dua langkah:
- Anda perlu melampirkan keseluruhan fungsi dalam kurungan. Seperti namanya, Iife mestilah ungkapan fungsi, bukan definisi fungsi. Oleh itu, tujuan melampirkan kurungan adalah untuk menukar definisi fungsi menjadi ungkapan. Ini kerana dalam JavaScript segala -galanya dalam kurungan dianggap sebagai ungkapan.
- anda perlu menambah sepasang kurungan pada akhir (variasi 1), atau selepas menutup pendakap (variasi 2), yang menyebabkan fungsi dilaksanakan dengan segera.
Tiga lagi perkara yang perlu diingat:
Pertama sekali, jika anda memberikan fungsi kepada pemboleh ubah, anda tidak perlu melampirkan keseluruhan fungsi dalam kurungan, kerana ia sudah menjadi ungkapan:
function printLocation () { console.log("You are in " + city + ", " + country); }
Kedua, IIFE berakhir dengan titik koma, jika tidak, kod anda mungkin tidak berfungsi dengan baik.
ketiga, anda boleh lulus parameter ke Iife (ia adalah fungsi selepas semua), seperti yang ditunjukkan dalam contoh berikut:
function cityLocation() { var city = "Paris"; return { get: function() { console.log(city); }, set: function(newCity) { city = newCity; } }; } var myLocation = cityLocation(); myLocation.get(); // 输出:Paris myLocation.set('Sydney'); myLocation.get(); // 输出:Sydney
Melewati objek global sebagai parameter kepada IIFE adalah corak yang sama untuk mengaksesnya di dalam fungsi tanpa menggunakan objek window
, yang menjadikan kod bebas dari persekitaran penyemak imbas. Kod berikut mencipta pembolehubah global
yang akan merujuk objek global tidak kira platform apa yang anda gunakan:
function showMessage(message) { setTimeout(function() { alert(message); }, 3000); } showMessage('Function called 3 seconds ago');
Kod ini berfungsi dalam penyemak imbas (objek global adalah window
) atau dalam persekitaran Node.js (kami menggunakan pembolehubah khas global
untuk merujuk kepada objek global).
Salah satu manfaat besar IIFE ialah apabila menggunakannya, anda tidak perlu bimbang tentang mencemarkan ruang global dengan pembolehubah sementara. Semua pembolehubah yang anda tentukan di dalam Iife akan menjadi tempatan. Mari kita periksa:
<!-- HTML --> <button id="btn">Click me</button> <!-- JavaScript --> function showMessage() { alert('Woohoo!'); } var el = document.getElementById("btn"); el.addEventListener("click", showMessage);
Dalam contoh ini, pernyataan pertama console.log()
berfungsi dengan baik, tetapi pernyataan kedua gagal kerana pembolehubah today
dan currentTime
menjadi pembolehubah tempatan kerana IIFE.
Kami sudah tahu bahawa penutupan mengekalkan rujukan kepada pembolehubah luaran, jadi mereka mengembalikan nilai terkini/terkini. Jadi, apa yang anda fikir adalah output contoh berikut?
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } printLocation(); } setLocation("Paris"); // 输出:You are in Paris, France
Anda mungkin mengharapkan nama buah itu dicetak satu demi satu pada selang saat. Walau bagaimanapun, sebenarnya, output adalah empat kali "undefined". Jadi, apa masalahnya?
Masalahnya ialah dalam pernyataan, nilai console.log()
sama dengan 4 untuk setiap lelaran gelung. Dan, kerana kita tidak mempunyai apa -apa pada pengindeksan 4 dalam array i
, output adalah "undefined". (Ingat, dalam JavaScript, indeks array bermula pada 0.) Apabila fruits
sama dengan 4, gelung itu berakhir. i
. Kami melakukan ini dengan mematikan kaedah i
dalam IIFE dan menentukan pemboleh ubah peribadi untuk memegang salinan semasa setTimeout()
. i
function setLocation(city) { var country = "France"; function printLocation() { console.log("You are in " + city + ", " + country); } return printLocation; } var currentLocation = setLocation("Paris"); currentLocation(); // 输出:You are in Paris, Francekita juga boleh menggunakan varian berikut, yang melakukan tugas yang sama:
function printLocation () { console.log("You are in " + city + ", " + country); }IIFE biasanya digunakan untuk membuat skop untuk merangkum modul. Di dalam modul ini, terdapat skop peribadi yang serba lengkap yang menghalang pengubahsuaian yang tidak disengajakan. Teknik ini dipanggil corak modul dan merupakan contoh yang kuat menggunakan skop pengurusan penutupan, yang digunakan secara meluas di banyak perpustakaan JavaScript moden seperti jquery dan garis bawah.
Kesimpulan
Tujuan tutorial ini adalah untuk memperkenalkan konsep -konsep asas ini dengan jelas dan ringkas mungkin -sebagai satu set prinsip atau peraturan yang mudah. Pemahaman yang baik tentang mereka adalah kunci untuk menjadi pemaju JavaScript yang berjaya dan cekap.Untuk menerangkan topik yang dibentangkan di sini dengan lebih terperinci dan mendalam, saya cadangkan anda membaca "Anda Tidak Tahu JS: Skop dan Penutupan" oleh Kyle Simpson.
(Kandungan berikutnya, iaitu bahagian FAQ, telah ditinggalkan kerana panjang artikel. Jika perlu, sila tanya soalan tertentu.)
Atas ialah kandungan terperinci Demystifying JavaScript Closures, Callbacks and Iifes. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

JavaScript digunakan secara meluas di laman web, aplikasi mudah alih, aplikasi desktop dan pengaturcaraan sisi pelayan. 1) Dalam pembangunan laman web, JavaScript mengendalikan DOM bersama -sama dengan HTML dan CSS untuk mencapai kesan dinamik dan menyokong rangka kerja seperti JQuery dan React. 2) Melalui reaktnatif dan ionik, JavaScript digunakan untuk membangunkan aplikasi mudah alih rentas platform. 3) Rangka kerja elektron membolehkan JavaScript membina aplikasi desktop. 4) Node.js membolehkan JavaScript berjalan di sisi pelayan dan menyokong permintaan serentak yang tinggi.

Python lebih sesuai untuk sains data dan automasi, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python berfungsi dengan baik dalam sains data dan pembelajaran mesin, menggunakan perpustakaan seperti numpy dan panda untuk pemprosesan data dan pemodelan. 2. Python adalah ringkas dan cekap dalam automasi dan skrip. 3. JavaScript sangat diperlukan dalam pembangunan front-end dan digunakan untuk membina laman web dinamik dan aplikasi satu halaman. 4. JavaScript memainkan peranan dalam pembangunan back-end melalui Node.js dan menyokong pembangunan stack penuh.

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

Dreamweaver Mac版
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

PhpStorm versi Mac
Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

Versi Mac WebStorm
Alat pembangunan JavaScript yang berguna