var foo = "hello"; var c = (function a () {function b () {var bar = "world"; alert (foo + bar); return bar;} return b;}) () (); waring (foo + c);Contoh ini muncul Hello World dua kali;
1. Apa itu penutupan?
Penjelasan "resmi" adalah: apa yang disebut "penutupan" mengacu pada ekspresi (biasanya fungsi) yang memiliki banyak variabel dan lingkungan yang terikat pada variabel-variabel ini, sehingga variabel-variabel ini juga merupakan bagian dari ekspresi.
Saya percaya hanya sedikit orang yang dapat secara langsung memahami kalimat ini karena dia menggambarkannya terlalu akademis. Saya ingin menggunakan cara membuat penutupan di JavaScript untuk memberi tahu Anda apa penutupan, karena sangat sulit untuk secara langsung memahami definisi penutupan dengan melewatkan proses pembuatan penutupan. Lihat kode berikut:
fungsi a () {var i = 0; fungsi b () {ware (++ i);} return b;} var c = a (); c ();Kode ini memiliki dua karakteristik:
1. Fungsi B adalah fungsi di dalam A;
2. Fungsi A Mengembalikan fungsi b.
Dengan cara ini, setelah mengeksekusi var c = a (), variabel C sebenarnya menunjuk berfungsi b. Setelah mengeksekusi C (), sebuah jendela akan muncul untuk menampilkan nilai i (pertama kali adalah 1). Kode ini sebenarnya membuat penutupan. Mengapa? Karena variabel C Fungsi luar A mengacu pada fungsi B dalam fungsi A, yaitu,:
Ketika fungsi internal B fungsi A dirujuk oleh fungsi luar variabel A, penutupan dibuat.
Saya kira Anda masih tidak mengerti penutupan karena Anda tidak tahu penutupan apa yang dimiliki. Mari kita terus jelajahi di bawah ini.
2. Apa fungsi penutupan?
Singkatnya, fungsi penutupan adalah bahwa setelah A dieksekusi dan dikembalikan, penutupan membuat mekanisme pengumpulan sampah JavaScript GC tidak memulihkan sumber daya yang ditempati oleh A, karena pelaksanaan fungsi internal B dari kebutuhan A mengandalkan variabel dalam a. Ini adalah deskripsi yang sangat mudah tentang peran penutupan, yang tidak profesional atau ketat, tetapi secara kasar berarti itu. Memahami penutupan membutuhkan proses bertahap.
Dalam contoh di atas, setelah fungsi A dikembalikan, saya selalu ada, jadi setiap kali C () dieksekusi, saya adalah nilai yang saya waspada setelah menambahkan 1.
Lalu mari kita bayangkan situasi lain. Jika A Returns Not Function B, situasinya sama sekali berbeda. Karena setelah A dieksekusi, B tidak dikembalikan ke dunia luar A, tetapi hanya direferensikan oleh A, dan pada saat ini A hanya akan dirujuk oleh B, jadi fungsi A dan B dirujuk satu sama lain tetapi tidak terganggu oleh dunia luar (dirujuk oleh dunia luar), fungsi A dan B akan diterapkan oleh GC. (Mekanisme pengumpulan sampah JavaScript akan diperkenalkan secara rinci nanti)
3. Dunia mikroskopis dalam penutupan
Jika kita ingin memiliki pemahaman yang lebih dalam tentang hubungan antara penutupan dan fungsi A dan fungsi bersarang B, kita perlu memperkenalkan beberapa konsep lain: lingkungan eksekusi fungsi (konteks ekskusi), objek aktif (objek panggilan), ruang lingkup (ruang lingkup), dan rantai ruang lingkup. Ambil proses fungsi dari definisi ke eksekusi sebagai contoh untuk menggambarkan konsep -konsep ini.
1. Saat mendefinisikan fungsi A, interpreter JS akan mengatur rantai lingkup fungsi A ke "lingkungan" di mana a berada saat mendefinisikan a. Jika A adalah fungsi global, hanya ada objek jendela dalam rantai lingkup.
2. Ketika fungsi A dieksekusi, A akan memasuki lingkungan eksekusi yang sesuai (konteks ekskusi).
3. Dalam proses menciptakan lingkungan eksekusi, A pertama -tama akan menambahkan atribut lingkup, yaitu ruang lingkup A, dan nilainya adalah rantai ruang lingkup pada langkah 1. Yaitu, rantai ruang lingkup a.scope = a.
4. Lingkungan eksekusi kemudian akan membuat objek aktif (objek panggilan). Objek aktif juga merupakan objek dengan atribut, tetapi tidak memiliki prototipe dan tidak dapat diakses secara langsung melalui kode JavaScript. Setelah membuat objek aktif, tambahkan objek aktif ke bagian atas rantai lingkup a. Pada saat ini, rantai lingkup A berisi dua objek: objek aktif A dan objek jendela.
5. Langkah selanjutnya adalah menambahkan atribut argumen ke objek aktif, yang menyimpan parameter yang dilewati saat memanggil fungsi a.
6. Akhirnya, tambahkan semua parameter formal fungsi A dan referensi ke fungsi internal B ke objek aktif a. Pada langkah ini, definisi fungsi B selesai, sehingga pada langkah 3, rantai lingkup fungsi B diatur ke lingkungan yang ditentukan oleh B, yaitu ruang lingkup a.
Pada titik ini, seluruh fungsi A diselesaikan dari definisi ke eksekusi. Pada saat ini A mengembalikan referensi ke fungsi B ke C, dan rantai lingkup fungsi B berisi referensi ke objek aktif fungsi A, yaitu, B dapat mengakses semua variabel dan fungsi yang ditentukan dalam a. Fungsi B dirujuk oleh C, dan fungsi B bergantung pada fungsi A, sehingga fungsi A tidak akan didaur ulang oleh GC setelah dikembalikan.
Ketika fungsi B dieksekusi, itu juga akan sama seperti di atas. Oleh karena itu, rantai lingkup B selama eksekusi berisi 3 objek: objek aktif B, objek aktif A dan objek jendela, seperti yang ditunjukkan pada gambar di bawah ini:
Seperti yang ditunjukkan pada gambar, ketika mengakses variabel dalam fungsi B, urutan pencarian adalah untuk mencari objek aktifnya sendiri, dan jika ada, ia akan kembali. Jika tidak ada, itu akan terus mencari objek aktif fungsi A, dan mencari pada gilirannya sampai ditemukan. Jika tidak dapat ditemukan di seluruh rantai ruang lingkup, tidak ditentukan dikembalikan. Jika ada objek prototipe prototipe untuk fungsi B, maka setelah mencari objek aktifnya sendiri, pertama -tama cari objek prototipe sendiri, dan kemudian terus mencari. Ini adalah mekanisme pencarian variabel dalam JavaScript.
4. Skenario Penutupan Aplikasi
1. Lindungi keamanan variabel dalam fungsi. Mengambil contoh pertama sebagai contoh, dalam fungsi A, saya hanya dapat diakses oleh fungsi B, tetapi tidak dapat diakses melalui saluran lain, sehingga melindungi keamanan i.
2. Pertahankan variabel dalam memori. Masih seperti sebelumnya, karena penutupan, saya berfungsi selalu ada dalam memori, jadi setiap kali C () dieksekusi, saya akan ditambahkan 1.
Dua poin di atas adalah skenario aplikasi paling dasar untuk penutupan, dan banyak kasus klasik berasal dari ini.
5. Mekanisme Pengumpulan Sampah Javascript
Dalam JavaScript, jika suatu objek tidak lagi dirujuk, maka objek akan didaur ulang oleh GC. Jika dua objek dirujuk satu sama lain dan tidak lagi dirujuk oleh orang ketiga, maka dua objek yang dirujuk satu sama lain akan didaur ulang. Karena fungsi A dirujuk oleh B, B dirujuk oleh C di luar A, itulah sebabnya fungsi A tidak akan didaur ulang setelah eksekusi.
Artikel di atas secara komprehensif memahami mekanisme penutupan adalah semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.