


Penjelasan terperinci tentang penutupan JavaScript_Pengetahuan asas
Dalam artikel yang lepas, kami memberikan gambaran pra-tafsiran Sebelum menulis catatan blog ini, kami bercadang untuk menulis beberapa kes klasik Memandangkan kes tersebut agak menyeluruh, kami menulis catatan blog ini secara berperingkat tentang Ia juga lebih mudah untuk mula belajar dan mendalami JavaScript.
Pendahuluan
Seorang rakan sekerja pergi untuk temu duga, dan penemuduga bertanya soalan: Bolehkah anda menulis penutup dan izinkan saya melihat? Jadi rakan sekerja saya dengan cepat menulis kod berikut:
fungsi fn(){
alert('Hello JavaScript Closure!!!'); // Alamak, teks E tidak bagus, jadi saya terpaksa mencari penterjemah untuk menulis perkataan penutup
}
fn();
Kemudian pewawancara menggelengkan kepalanya dan berkata: "Bagaimana ini boleh dipanggil penutupan?" (Kisah ini adalah rekaan semata-mata, sebarang persamaan adalah kebetulan semata-mata)
Penutupan mungkin merupakan teknologi "mewah dan sukar untuk dipelajari" di mata ramai orang, mungkin pada pandangan ramai orang, ini adalah satu-satunya cara ia boleh dianggap sebagai penutupan:
Contoh 1:
fungsi fn() {
Kembalikan fungsi () {
makluman('Contoh 1');
}
}
fn()();
Contoh 1 PS: Ini tidak kelihatan sangat maju, nampaknya orang ini tidak begitu baik!
Contoh 2:
;(fungsi () {
makluman('Contoh 2');
})();
Contoh 2 PS: Yang ini kelihatan lebih maju daripada yang sebelumnya, dan koma bertitik ditambah sebelum kurungan pertama Mengapa menambah koma bertitik Baik, mari tinggalkan soalan ini di sini dan akan membincangkannya kemudian.
Contoh 3:
~fungsi fn() {
makluman('Contoh 3')
}();
Contoh 3 PS: Ini adalah yang paling maju, saya tidak banyak membaca, jadi jangan berbohong kepada saya!
Saya tidak banyak membaca, jadi saya hanya boleh menulis tiga jenis "penutupan" ini sudah tahu mekanisme bagaimana fungsi itu berjalan. Saya benar-benar tidak mahu menambah skop ini kepada tajuk ini. Tabiat lama, kod dahulu:
var n = 10;
fungsi fn(){
makluman(n);
var n = 9;
makluman(n);
}
fn();
Ringkasnya, mari lukis gambar (pengarang hanya akan menggunakan perisian lukisan yang disertakan dengan Windows. Jika ada yang lebih baik, sila syorkannya) untuk menganalisisnya:
Analisis 1
Dari gambar kita lihat dua skop, satu adalah skop tetingkap (skop peringkat atas), dan satu lagi adalah skop peribadi yang terbentuk apabila fn dipanggil; maka apa itu skop, skop sebenarnya adalah persekitaran pelaksanaan kod. Sebagai contoh, persekitaran pembelajaran pelajar adalah sekolah, yang setara dengan skopnya Jika pelajar ini sangat nakal dan sering pergi ke kafe Internet untuk bermain permainan pada waktu malam, ia bersamaan dengan membentuk persekitaran peribadi, dan skop ini adalah. Kafe internet. Baiklah! Berangan ini kelihatan sangat sial seperti melancap itu sendiri sehingga saya tidak dapat menahan nafas: "Jika anda tidak bekerja keras semasa anda muda, anda akan ditendang apabila anda dewasa." Berbalik kepada topik, sebenarnya definisi fungsi fn adalah untuk menunjuk kepada penerangan sekeping kod (kotak merah dalam gambar Apabila fn dipanggil (kotak hijau dalam gambar), skop akan terbentuk. Sudah tentu, dalam skop ini Kod ini juga akan ditafsirkan sebelum pelaksanaan. Saya tidak akan memberitahu anda bahawa skop ini akan dimusnahkan selepas ia dilaksanakan semula juga akan membentuk skop baharu, dan kemudiannya sebelum ini pelaksanaan, dan kemudian kod itu akan dimusnahkan selepas pelaksanaan akhir.
Memahami penutupan
Kita tahu bahawa apabila fungsi dipanggil, ia akan membentuk skop peribadi (persekitaran pelaksanaan), dan skop peribadi ini adalah penutupan. Mengimbas kembali, adakah penutupan masih legenda "tinggi dan sukar untuk dikuasai"? Mari kita lihat kembali kisah temu bual pertama dan tiga contoh yang saya tulis itu sebenarnya penutupan.
Senario aplikasi
Sekarang terdapat keperluan sedemikian: terdapat teg ul dalam halaman HTML, dan terdapat 5 teg li di bawah ul. Ia diperlukan untuk mengklik pada mana-mana li, dan indeks (indeks bermula dari 0) kedudukan li yang diklik akan muncul, dan struktur HTML Seperti berikut:
- Senarai 1
- Senarai 2
- Senarai 3
- Senarai 4
- Senarai 5
Oleh kerana bijak, saya dengan pantas menulis kod berikut:
var lis = document.getElementById('ul').getElementsByTagName('li');
untuk (var i = 0, len = lis.length; i < len; i ) {
lis[i].onclick = fungsi () {
makluman(i);
};
}
Ujian akhir untuk melihat sama ada keperluan ini direalisasikan dengan sempurna:
Saya mendapati bahawa tidak kira berapa kali saya mengklik, keputusan ini akhirnya akan muncul, dan hasil yang diinginkan ialah: klik pada senarai 1 untuk muncul 0, klik pada senarai 2 untuk muncul 1, klik pada senarai 3 hingga timbul 2... Saya hanya mahu menggunakan gambar ini pada masa ini Untuk menggambarkan mood semasa saya:
(Bagaimana rupa apabila prototaip gagal berjalan seperti yang direka semasa demonstrasi)
Bagaimana ini boleh dilakukan Mengapa 5 sentiasa muncul? Secara teorinya betul! Mari lukis gambar untuk menganalisisnya:
Sebenarnya onclick yang kami berikan kepada setiap li sebenarnya adalah rentetan penerangan yang disimpan bagi sesuatu fungsi. Kandungan rentetan ini ialah kandungan dalam kotak merah dalam gambar di atas mempunyai gambar dengan kebenaran:
Masukkan: lis[4].onklik dalam konsol Chrome, nilainya ialah perihalan fungsi. Apabila kita mengklik pada senarai kelima, ia sebenarnya bersamaan dengan lis[4].onclick() Penerangan fungsi ini dipanggil skop juga dipratafsirkan terlebih dahulu, dan kemudian kod dilaksanakan Pada masa ini, i tidak ada dalam skop peribadi semasa, dan kemudian saya ditemui dalam skop tetingkap, jadi 5 muncul setiap kali anda. klik.
Jelas sekali kod di atas tidak dapat memenuhi keperluan ini. Adalah salah untuk kita menulis kod seperti itu. Sebenarnya, sebabnya ialah setiap kali anda klik, anda membaca i di bawah tetingkap Pada masa ini, nilai i sudah 5, jadi anda mempunyai kod berikut:
Kaedah 1:
var lis = document.getElementById('ul').getElementsByTagName('li');
fungsi fn(i) {
Kembalikan fungsi () {
makluman(i);
}
}
untuk (var i = 0, len = lis.length; i < len; i ) {
lis[i].onclick = fn(i);
}
Kaedah 2:
var lis = document.getElementById('ul').getElementsByTagName('li');
untuk (var i = 0, len = lis.length; i < len; i ) {
;(fungsi (i) {
lis[i].onclick = fungsi () {
makluman(i);
};
})(i);
}
Kaedah 3:
var lis = document.getElementById('ul').getElementsByTagName('li');
untuk (var i = 0, len = lis.length; i < len; i ) {
lis[i].onclick = fungsi fn(i) {
mengembalikan fungsi () {
makluman(i);
}
}(i);
}
Ich habe drei Methoden in einem Atemzug geschrieben, nämlich die Variable i in einer privaten Variablen zu speichern. Hier werde ich natürlich nur über die zweite Methode sprechen werde den Rest verstehen. Wie üblich zeichnen wir Bilder zur schrittweisen Analyse:
Ich habe die gesamte Codeausführung im Detail beschrieben. Es ist zu beachten, dass das Onclick-Attribut jedes Li den Bereich (function(i){…})(i) belegen muss zerstört werden, da es von einem externen LI belegt ist (dieses LI befindet sich im Fensterbereich), sodass dieser Bereich nicht zerstört wird. Wenn auf ein beliebiges li geklickt wird, wird function(){ warning(i); } ausgeführt und ein Bereich erstellt. Dieser Bereich hat kein i und geht zu (function(){ ... })(. i) Finden Sie i und schließlich den Wert dieses formalen Parameters i, der während der for-Schleife übergeben wird, um Werte zu speichern, was das Problem perfekt löst.
PS: Ich habe gerade erwähnt, warum vor (function(i){ … })(i) ein Semikolon eingefügt wird. Der Grund besteht darin, zu verhindern, dass die vorherige Anweisung vergisst, ein Semikolon hinzuzufügen, was zu JavaScript-Fehlern führt Parsen. Das ist alles. Eines der oben genannten Anwendungsszenarien ist natürlich das Implementierungsprinzip von Tabs. Es kann auch andere Implementierungsmethoden geben, z. B. benutzerdefinierte Attributmethoden und die Suche nach Indizes über DOM-Knotenbeziehungen. Der Hauptzweck der Verwendung dieser Methode besteht darin, das Verständnis von Abschlüssen zu vertiefen .
Zusammenfassung
Schließungen sind nicht die legendären, die schwer zu beherrschen sind. Wenn eine Funktion aufgerufen wird, wird ein neuer privater Bereich gebildet Dieser Bereich wird nicht zerstört. Lu Zhu hat sehr wenig gelesen, daher möchte ich meine Blogger-Kollegen bitten, mich zu korrigieren, wenn ich falsch liege. Ich möchte mich auch bei allen für ihre Unterstützung der Artikel von Lu Zhu bedanken.

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

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas





Dalam C++, penutupan ialah ungkapan lambda yang boleh mengakses pembolehubah luaran. Untuk membuat penutupan, tangkap pembolehubah luar dalam ungkapan lambda. Penutupan memberikan kelebihan seperti kebolehgunaan semula, penyembunyian maklumat dan penilaian malas. Ia berguna dalam situasi dunia sebenar seperti pengendali acara, di mana penutupan masih boleh mengakses pembolehubah luar walaupun ia dimusnahkan.

Ungkapan C++ Lambda menyokong penutupan, yang menyimpan pembolehubah skop fungsi dan menjadikannya boleh diakses oleh fungsi. Sintaks ialah [capture-list](parameters)->return-type{function-body}. capture-list mentakrifkan pembolehubah untuk ditangkap Anda boleh menggunakan [=] untuk menangkap semua pembolehubah tempatan mengikut nilai, [&] untuk menangkap semua pembolehubah tempatan melalui rujukan, atau [variable1, variable2,...] untuk menangkap pembolehubah tertentu. Ungkapan Lambda hanya boleh mengakses pembolehubah yang ditangkap tetapi tidak boleh mengubah suai nilai asal.

Penutupan ialah fungsi bersarang yang boleh mengakses pembolehubah dalam skop fungsi luar Kelebihannya termasuk pengkapsulan data, pengekalan keadaan dan fleksibiliti. Kelemahan termasuk penggunaan memori, kesan prestasi dan kerumitan penyahpepijatan. Selain itu, penutupan boleh mencipta fungsi tanpa nama dan menyerahkannya kepada fungsi lain sebagai panggilan balik atau hujah.

Tajuk: Kebocoran memori disebabkan oleh penutupan dan penyelesaian Pengenalan: Penutupan ialah konsep yang sangat biasa dalam JavaScript, yang membenarkan fungsi dalaman mengakses pembolehubah fungsi luaran. Walau bagaimanapun, penutupan boleh menyebabkan kebocoran memori jika digunakan secara tidak betul. Artikel ini akan meneroka masalah kebocoran memori yang disebabkan oleh penutupan dan menyediakan penyelesaian serta contoh kod khusus. 1. Kebocoran memori disebabkan oleh penutupan Ciri penutupan ialah fungsi dalaman boleh mengakses pembolehubah fungsi luaran, yang bermaksud pembolehubah yang dirujuk dalam penutupan tidak akan dikumpul sampah. Jika digunakan secara tidak betul,

Kesan penunjuk fungsi dan penutupan pada prestasi Go adalah seperti berikut: Penunjuk fungsi: Lebih perlahan sedikit daripada panggilan langsung, tetapi meningkatkan kebolehbacaan dan kebolehgunaan semula. Penutupan: Biasanya lebih perlahan, tetapi merangkumi data dan tingkah laku. Kes praktikal: Penunjuk fungsi boleh mengoptimumkan algoritma pengisihan dan penutupan boleh mencipta pengendali acara, tetapi ia akan membawa kerugian prestasi.

Penutupan fungsi bahasa Go memainkan peranan penting dalam ujian unit: Menangkap nilai: Penutupan boleh mengakses pembolehubah dalam skop luar, membenarkan parameter ujian ditangkap dan digunakan semula dalam fungsi bersarang. Permudahkan kod ujian: Dengan menangkap nilai, penutupan memudahkan kod ujian dengan menghapuskan keperluan untuk menetapkan parameter berulang kali untuk setiap gelung. Tingkatkan kebolehbacaan: Gunakan penutupan untuk mengatur logik ujian, menjadikan kod ujian lebih jelas dan lebih mudah dibaca.

Ya, kesederhanaan dan kebolehbacaan kod boleh dioptimumkan melalui panggilan berantai dan penutupan: panggilan berantai memaut fungsi panggilan ke antara muka yang lancar. Penutupan mewujudkan blok kod yang boleh digunakan semula dan pembolehubah akses di luar fungsi.

Penutupan dalam Java membenarkan fungsi dalaman mengakses pembolehubah skop luar walaupun fungsi luar telah keluar. Dilaksanakan melalui kelas dalaman tanpa nama, kelas dalam memegang rujukan kepada kelas luar dan memastikan pembolehubah luar aktif. Penutupan meningkatkan fleksibiliti kod, tetapi anda perlu sedar tentang risiko kebocoran memori kerana rujukan kepada pembolehubah luaran oleh kelas dalaman tanpa nama memastikan pembolehubah tersebut hidup.
