1. Apa itu penutupan
Penutupan adalah fungsi yang memiliki izin untuk mengakses variabel dalam ruang lingkup fungsi lain.
Sederhananya, JavaScript memungkinkan penggunaan fungsi internal - yaitu, definisi fungsi dan ekspresi fungsi terletak di badan fungsi fungsi lain. Selain itu, fungsi internal ini dapat mengakses semua variabel lokal, parameter, dan fungsi internal lainnya yang dinyatakan dalam fungsi eksternal tempat mereka tinggal. Ketika salah satu fungsi internal ini disebut di luar fungsi eksternal yang mengandungnya, penutupan terbentuk.
2. Lingkup variabel
Untuk memahami penutupan, Anda harus terlebih dahulu memahami ruang lingkup variabel.
Hanya ada dua jenis lingkup variabel: variabel global dan variabel lokal.
Fitur khusus bahasa JavaScript adalah bahwa variabel global dapat dibaca secara langsung dalam fungsi.
Variabel fungsi eksternal dapat diakses dalam fungsi internal karena rantai ruang lingkup fungsi internal berisi ruang lingkup fungsi eksternal;
Ini juga dapat dipahami sebagai: rentang aksi fungsi internal memancar ke rentang aksi fungsi eksternal;
var n = 999; function f1 () {alert (n);} f1 (); // 999Di sisi lain, variabel lokal di dalam fungsi secara alami tidak dibaca di luar fungsi.
fungsi f1 () {var n = 999;} alert (n); // kesalahanAda tempat yang perlu diperhatikan di sini. Saat mendeklarasikan variabel secara internal, Anda harus menggunakan perintah VAR. Jika tidak, Anda benar -benar menyatakan variabel global!
fungsi f1 () {n = 999;} f1 (); peringatan (n); // 9993. Beberapa cara untuk menulis dan menggunakan penutupan
3.1. Tambahkan beberapa properti ke fungsi
function circle (r) {this.r = r; } Circle.pi = 3.14159; Circle.prototype.area = function () {return circle.pi * this.r * this.r; } var c = lingkaran baru (1.0); peringatan (c.area ()); //3.141593.2. Mendeklarasikan variabel dan menetapkan fungsi ke variabel sebagai nilai.
var circle = function () {var obj = objek baru (); obj.pi = 3.14159; obj.area = function (r) {return this.pi * r * r; } kembalikan obj; } var c = new circle (); Peringatan (C.Area (1.0)); //3.141593.3. Metode ini digunakan lebih sering dan merupakan yang paling nyaman. var obj = {} adalah untuk mendeklarasikan objek kosong
var circle = {"pi": 3.14159, "Area": function (r) {return this.pi * r * r; }}; Peringatan (Circle.area (1.0)); // 3.141594. Fungsi utama 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.
4.1. 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 f1 () {var n = 999; function f2 () {alert (n); // 999}}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?
fungsi f1 () {var n = 999; function f2 () {alert (n); } return f2;} var result = f1 (); result (); // 9994.2. Bagaimana cara selalu menyimpan nilai variabel dalam memori?
fungsi f1 () {var n = 999; nadd = function () {n+= 1} function f2 () {alert (n); } return f2;} var result = f1 (); result (); // 999nadd (); result (); // 1000Dalam 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. Penutupan dan objek ini
Menggunakan objek ini dalam penutupan dapat menyebabkan beberapa masalah. Karena pelaksanaan fungsi anonim bersifat global, objek ini biasanya menunjuk ke jendela. Kodenya adalah sebagai berikut:
var name = "the window"; var objek = {name: "Object saya", getNamefun: function () {return function () {return this.name;};}}; waspada (object.getNamefun () {}); // "jendela" (dalam mode non-ketat)Simpan objek ini dalam ruang lingkup eksternal dalam variabel yang dapat diakses dengan penutupan, dan penutupan dapat mengakses objek. Kodenya adalah sebagai berikut:
var name = "the window"; var objek = {name: "Object saya", getNamefun: function () {var that = this; return function () {return that.name;};}}; alert (object.getNamefun () {}); // "objek saya"6. Penutupan dan kebocoran memori
Secara khusus, jika elemen HTML disimpan dalam ruang lingkup penutupan, itu berarti bahwa elemen tidak dapat dihancurkan. sebagai berikut:
function assignhandler () {var element = document.geteLementById ("someElement"); element.onClick = function () {alert (element.id);}}Kode di atas membuat penutupan sebagai penangan acara elemen elemen, dan penutupan ini membuat referensi melingkar. Karena fungsi anonim menyimpan referensi ke objek aktif AssignHandler (), tidak mungkin untuk mengurangi jumlah referensi ke elemen. Selama ada fungsi anonim, jumlah referensi ke elemen setidaknya 1, sehingga memori yang ditempati tidak akan didaur ulang.
Menyelesaikan masalah daur ulang internal dengan menulis ulang kode:
function assignhandler () {var element = document.geteLementById ("someElement"); var id = element.id; element.onClick = function () {alert (id);} element = null;}Dalam kode di atas, penutupan implementasi tidak secara langsung merujuk ke elemen, dan referensi masih akan disimpan dalam objek aktif yang berisi fungsi. Oleh karena itu, perlu untuk mengatur variabel elemen ke nol, sehingga memori yang ditempati dapat didaur ulang secara normal.
7. 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.
Di atas adalah penjelasan terperinci tentang penulisan dan fungsi penutupan dalam JavaScript yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!