Penutupan adalah kesulitan dalam bahasa JavaScript dan fiturnya. Banyak aplikasi canggih bergantung pada penutupan untuk diterapkan. Saya telah terpapar pada konsep penutupan untuk waktu yang lama, tetapi saya telah bingung dan belum dapat memahami apa itu penutupan javascript dan apa yang berguna. Hari ini saya melihat artikel tentang penutupan JavaScript (tautan asli) di internet. Itu dijelaskan dengan sangat baik. Sekarang saya benar -benar mengerti bahwa penutupan javascript adalah hal yang ajaib dan tujuan penutupan. Saya akan menulisnya di sini untuk berbagi dengan Anda. Saya berharap teman -teman yang tidak mengerti penutupan javascript dapat memahami penutupan setelah membacanya! Sebagian besar konten berikut berasal dari teks asli. Saya menambahkan beberapa komentar kode, rendering operasi dan sedikit modifikasi pada teks asli untuk pemahaman yang mudah!
1. Lingkup variabel
Untuk memahami penutupan, Anda harus terlebih dahulu memahami ruang lingkup variabel khusus JavaScript.
Dalam JavaScript, ruang lingkup variabel dibagi menjadi dua jenis: variabel global dan variabel lokal.
Dalam JavaScript, variabel global dapat dibaca langsung di dalam fungsi.
var n =; // Tentukan variabel global nfunction f () {alert ("akses variabel global n, n ="+n); // akses variabel global n} f (); //Hasil Menjalankan:
Tetapi sebaliknya tidak mungkin, variabel lokal di dalam fungsi tidak dapat dibaca di luar fungsi.
fungsi f () {var n =; // Tentukan variabel lokal n} peringatan ("akses variabel lokal n di luar fungsi, n ="+n); // akses variabel lokal n di luar fungsi, kesalahan: n tidak ditentukanHasil Menjalankan:
Ada tempat yang perlu diperhatikan di sini. Saat mendeklarasikan variabel secara internal, Anda harus menggunakan perintah VAR. Jika tidak, itu sebenarnya variabel global yang dinyatakan!
fungsi f () {n =;} f (); peringatan ("n tidak dinyatakan dengan var di dalam fungsi f1, pada saat ini n adalah variabel global, /r /n bukti: n ="+n+", hasil dari window.n == n adalah:"+(window.n == n)));Hasil Menjalankan:
2. Bagaimana cara membaca variabel lokal dari luar?
Karena berbagai alasan, kadang -kadang kita perlu mendapatkan variabel lokal dalam fungsi. Namun, seperti yang disebutkan sebelumnya, dalam keadaan normal, ini tidak dapat dilakukan dan hanya dapat dicapai melalui solusi.
Yaitu mendefinisikan fungsi lain di dalam fungsi.
fungsi f () {var n =; // variabel lokal n di dalam fungsi f // tentukan fungsi f fungsi f f () {// di dalam fungsi f, peringatan (n); //}}Dalam kode di atas, fungsi F2 termasuk dalam fungsi F1, dan semua variabel lokal di dalam F1 terlihat oleh F2. Tapi sebaliknya tidak mungkin. Variabel lokal di dalam F2 tidak terlihat oleh F1. Ini adalah struktur "ruang lingkup rantai" yang unik untuk bahasa JavaScript. Objek anak akan terlihat ke atas level demi level untuk semua variabel objek induk. Oleh karena itu, semua variabel objek induk terlihat oleh objek anak, jika tidak itu tidak benar. Karena F2 dapat membaca variabel lokal di F1, selama F2 digunakan sebagai nilai pengembalian, tidak bisakah kita membaca variabel internalnya di luar F1? Beberapa orang mungkin memiliki pertanyaan. F2 adalah fungsi, bagaimana bisa dikembalikan sebagai nilai pengembalian fungsi F1? Bahkan, tidak apa -apa. Nama fungsi dalam JavaScript sendiri adalah variabel, sehingga fungsi juga dapat digunakan sebagai variabel normal. Artinya, tidak hanya satu fungsi dapat diteruskan ke fungsi lain seperti parameter lewat, tetapi satu fungsi juga dapat dikembalikan sebagai nilai pengembalian fungsi lain.
fungsi f () {var n =; // variabel lokal n // f fungsi dinyatakan di dalam fungsi f f () {alert (n); } return f; // Gunakan fungsi f sebagai nilai pengembalian fungsi f} var result = f (); // Nilai pengembalian setelah F dipanggil adalah fungsi f, dan hasilnya adalah fungsi f hasil (); // 999, hubungi fungsi F2Hasil Menjalankan:
3. Konsep penutupan
Fungsi F2 di bagian kode sebelumnya adalah penutupan. Definisi "penutupan" dalam berbagai dokumen profesional sangat abstrak. Misalnya, ada definisi penutupan: "Penutupan JavaScript adalah variabel yang diperoleh dari fungsi atau ruang lingkup level sebelumnya dalam ruang lingkup lain, dan variabel -variabel ini tidak akan dihancurkan karena pelaksanaan fungsi level sebelumnya selesai." Sulit bagi saya untuk memahami definisi penutupan seperti itu. Pemahaman saya adalah bahwa penutupan adalah fungsi yang dapat membaca variabel di dalam fungsi lain. Karena dalam bahasa JavaScript, hanya subfungsi di dalam fungsi yang dapat membaca variabel lokal, penutupan dapat dengan mudah dipahami sebagai "fungsi yang didefinisikan di dalam fungsi". Jadi, pada dasarnya, penutupan adalah jembatan yang menghubungkan bagian dalam dan bagian luar fungsi.
4. Tujuan penutupan
Penutupan dapat digunakan di banyak tempat. Ini memiliki dua kegunaan terbesar, satu adalah bahwa variabel di dalam fungsi dapat dibaca seperti yang disebutkan di atas, dan yang lainnya adalah bahwa nilai -nilai variabel ini selalu disimpan dalam memori.
Bagaimana cara memahami kalimat ini? Silakan lihat kode di bawah ini.
fungsi f () {var n =; // nadd adalah variabel global yang tidak dinyatakan menggunakan var. Variabel ini sekarang menunjuk ke fungsi anonim yang dideklarasikan di dalam fungsi f nadd = function () {n+=} function f () {alert (n); } return f; } var result = f (); // hasil adalah hasil fungsi f (); // panggilan pertama ke fungsi hasil nadd (); // nadd mewakili fungsi anonim yang dinyatakan di dalam fungsi f, nadd () adalah hasil fungsi anonim (); // panggilan kedua ke fungsi hasil 1000Hasil Menjalankan:
Dalam kode ini, hasilnya sebenarnya adalah fungsi penutupan F2. Total berjalan dua kali, nilai pertama adalah 999 dan nilai kedua adalah 1000. Ini membuktikan bahwa variabel lokal N dalam fungsi F1 telah disimpan dalam memori dan tidak secara otomatis dibersihkan setelah F1 dipanggil.
Mengapa ini terjadi? Alasannya adalah bahwa F1 adalah fungsi induk dari F2, dan F2 ditugaskan ke variabel global, yang menyebabkan F2 selalu ada dalam memori, dan keberadaan F2 tergantung pada F1. Oleh karena itu, F1 selalu dalam memori dan tidak akan didaur ulang oleh mekanisme pengumpulan sampah setelah panggilan selesai.
Titik penting lainnya dalam kode ini adalah bahwa baris "nadd = function () {n+= 1}" pertama kali digunakan sebelum NADD, jadi NADD adalah variabel global, bukan variabel lokal. Kedua, nilai NADD adalah fungsi anonim, dan fungsi anonim ini sendiri juga merupakan penutupan, sehingga NADD setara dengan setter, yang dapat beroperasi pada variabel lokal di dalam fungsi di luar fungsi.
5. Catatan tentang penggunaan penutupan
1) Karena penutupan akan menyebabkan semua variabel dalam fungsi disimpan dalam memori, dan konsumsi memori sangat besar, penutupan tidak dapat disalahgunakan, jika tidak itu akan menyebabkan masalah kinerja halaman web dan dapat menyebabkan kebocoran memori di IE. Solusinya adalah menghapus semua variabel lokal yang tidak digunakan sebelum keluar dari fungsi.
2) Penutupan akan mengubah nilai variabel di dalam fungsi induk di luar fungsi induk. Oleh karena itu, jika Anda menggunakan fungsi induk sebagai objek, gunakan penutupan sebagai metode publiknya, dan gunakan variabel internal sebagai properti pribadi, berhati -hatilah untuk tidak mengubah nilai variabel internal fungsi induk sesuka hati.
6. Pertanyaan berpikir
Jika Anda dapat memahami hasil berjalan dari dua potong kode berikut, Anda harus dianggap memahami mekanisme berjalan dari penutupan.
Cuplikan Kode 1:
var name = "the window"; var objek = {name: "Object saya", getNamefunc: function () {return function () {return this.name; }; }}; alert (object.getNamefunc () () ());Hasil Menjalankan:
Cuplikan Kode Dua:
var name = "the window"; var objek = {name: "Objek saya", getNamefunc: function () {var that = this; return function () {return that.name; }; }}; alert (object.getnamefunct () ());Hasil Menjalankan:
Komentar berikut ditambahkan ke kode untuk menganalisis hasil berjalan dari dua cuplikan kode di atas:
Cuplikan Kode 1:
Analisisnya adalah sebagai berikut:
/*Dalam JavaScript, objek global JavaScript, fungsi global dan variabel global yang kami nyatakan secara otomatis akan menjadi anggota objek jendela. Variabel global adalah sifat objek jendela. Fungsi global adalah metode objek jendela. */var name = "the window"; // Deklarasikan nama variabel global, dan pada saat ini nama variabel global akan secara otomatis menjadi atribut objek jendela // Bukti: peringatan ("window.name:"+window.name); // Anda dapat mengakses nama global ini secara otomatis. Objek Objek Variabel Global akan secara otomatis menjadi atribut dari objek jendela objek var objek = {nama: "objek saya", // Atribut nama objek getNamefunc: function () {// GetNamefunc Function objek objek // Nilai pengembalian objek yang ada di mana objek yang ada di mana objek yang ada. // Buktikan bahwa ini dalam fungsi anonim mewakili objek jendela alih -alih ObjectAlert ("Ini == Hasil objek adalah:"+(ini == objek)); alert ("Ini == Hasil jendela adalah:"+(jendela ini ==)); kembalikan this.name; // karena ini mewakili objek jendela, maka ini.name secara alami mengakses nama objek jendela "jendela"}; }}; // Bukti: Objek objek global adalah atribut dari peringatan objek jendela ("window.object:"+window.Object); peringatan ("window.object.name:"+window.object.name);/*Setelah memanggil metode getNamefunc, metode anonim dikembalikan. Pada saat ini, Retfn mewakili metode anonim. Sekarang setara dengan memberikan metode anonim nama retfn. Pada saat ini, fungsi Retfn secara otomatis menjadi fungsi dari objek jendela*/var retfn = object.getnamefunc (); waspada (retfn ()); // memanggil metode anonim yang dikembalikan, jadi siapa yang menyebut metode anonim ini? Ini adalah objek jendela // Bukti: Fungsi Retfn adalah fungsi dari peringatan objek jendela ("window.retfn ():"+window.retfn ()); // Anda dapat memanggil metode retfn dalam bentuk window.retfn () (Nama Objek. Metode), maka itu membuktikan bahwa fungsi Retfn adalah fungsi dari objek jendela jendela WindowCuplikan Kode Dua:
Analisisnya adalah sebagai berikut:
var name = "the window"; // nama variabel global // objek objek global objek = {name: "objek saya", getNamefunc: function () {/*Objek mana yang mewakili ini saat ini? Ini mewakili objek objek. Objek mana yang disebut fungsi di mana ini berada? Ini mengacu pada objek mana yang telah dieksekusi itu = ini, dan itu juga mewakili objek objek*/var bahwa = this; // itu adalah variabel lokal yang dinyatakan dalam fungsi getNamefunc // Buktikan bahwa ini dalam fungsi getNamefunc mewakili objek objek alih -alih windowalert ("ini == hasil objek adalah:"+(objek == ini)); alert ("Ini == Hasil jendela adalah:"+(jendela ini ==)); // Buktikan yang mewakili peringatan objek objek ("bahwa == hasil objek adalah:"+(itu == objek)); return function () {/*Itu adalah variabel lokal yang dinyatakan dalam fungsi getNamefunc. Dalam keadaan normal, setelah panggilan fungsi getNamefunc selesai, variabel lokal yang akan didaur ulang oleh GC Javascript, membebaskan ruang memori yang ditempati oleh variabel lokal yang, tetapi sekarang yang dapat digunakan secara normal dan belum didaur ulang. Alasannya adalah bahwa GetNamefunc adalah fungsi induk dari fungsi anonim. Setelah fungsi GetNamefunc dipanggil, fungsi anonim akan dikembalikan dan ditugaskan ke variabel global RETFN, yang menyebabkan fungsi anonim selalu ada dalam memori, dan keberadaan fungsi anonim tergantung pada fungsi getNamefunc. Oleh karena itu, fungsi getNamefunc selalu dalam memori dan tidak akan didaur ulang oleh mekanisme pengumpulan sampah setelah panggilan selesai. Karena fungsi getNamefunc selalu dalam memori, variabel lokal yang dinyatakan di dalam fungsi getNamefunc akan selalu ada dalam memori. Karena ada, tentu saja dapat terus digunakan. */kembalikan itu.name; // yang mewakili objek objek, sehingga itu. }}; var retfn = object.getNamefunc (); // Setelah memanggil metode getNamefunc, metode anonim dikembalikan. Pada saat ini, Retfn mewakili metode anonim, yang sekarang setara dengan memberikan metode anonim nama adalah retfn alert (retfn ());Akhirnya, saya juga melampirkan contoh yang saya tulis ketika saya mempelajari penutupan javascript sebelumnya:
<script type = "text/javaScript"> function a () {var i =; // mendeklarasikan variabel lokal i di dalam fungsi a/mendeklarasikan subfungsi bfunction b () {waspada ("i ="+(++ i); // mengakses variabel lokal saya mendeklarasikan fungsi di dalam fungsi a} return b; // return alamat b} variabel b; B. B. Variabel saya digunakan. Setelah mengeksekusi C (), jendela akan muncul untuk menampilkan nilai i (pertama kali) dan kode ini benar -benar membuat penutupan, karena variabel C di luar fungsi A mengacu pada fungsi B di dalam fungsi a. Artinya: ketika fungsi internal B fungsi A dirujuk oleh fungsi luar variabel A, penutupan "penutupan" yang disebut dibuat. Setelah A telah dieksekusi dan dikembalikan, penutupan membuat mekanisme pengumpulan sampah JavaScript GC tidak akan mendaur ulang sumber daya yang ditempati oleh A, karena pelaksanaan fungsi internal B dari suatu kebutuhan untuk mengandalkan variabel dalam a */a (); // pasti akan ada ruang dalam memori. Setelah A () dieksekusi, GC akan mendaur ulang ruang memori yang dialokasikan untuk i var c = a (); // penggunaan ini, gc tidak akan memperlakukan saya sebagai sampah dan c (); // setara dengan memanggil b (), hasilnya adalah: i = c (); // Hasilnya adalah: i = c (); // Hasilnya adalah: i = c (); // Hasilnya adalah: i = c (); // Hasilnya adalah: i = c ();Hasil Menjalankan:
Konten di atas adalah penjelasan terperinci dari kode penutupan JavaScript (penutupan) dari poin pengetahuan JavaScript yang dirangkum (16) yang diperkenalkan oleh editor. Saya harap ini akan membantu semua orang!