Salah satu fitur terpenting dalam JavaScript adalah penggunaan penutupan. Karena penggunaan penutupan, ruang lingkup saat ini selalu dapat mengakses lingkup eksternal. Karena JavaScript tidak memiliki ruang lingkup tingkat blok dan hanya ruang lingkup fungsi, penggunaan penutupan terkait erat dengan fungsi.
Mensimulasikan variabel pribadi
Salinan kode adalah sebagai berikut:
function counter (start) {
var count = mulai;
kembali {
increment: function () {
Count ++;
},
get: function () {
jumlah pengembalian;
}
}
}
var foo = counter (4);
foo.increment ();
foo.get (); // 5
Di sini penghitung mengembalikan dua penutupan: kenaikan fungsi dan dapatkan. Dua fungsi ini mempertahankan akses ke ruang lingkup penghitung, sehingga mereka dapat mengakses jumlah variabel yang ditentukan dalam ruang lingkup penghitungan.
Mekanisme kerja variabel pribadi
Karena JavaScript tidak dapat menetapkan nilai dan referensi untuk lingkup, dalam contoh di atas, tidak ada cara untuk secara langsung mengakses jumlah variabel pribadi internal dari luar. Satu -satunya cara adalah mengaksesnya dengan mendefinisikan penutupan.
Salinan kode adalah sebagai berikut:
var foo = counter baru (4);
foo.hack = function () {
hitung = 1337;
};
Kode di atas tidak mengubah nilai variabel penghitungan dalam ruang lingkup penghitung, karena hack tidak didefinisikan dalam penghitung. Kode di atas hanya akan membuat atau menimpa jumlah variabel global.
Penutupan di Loop
Salah satu kesalahan termudah adalah menggunakan penutupan dalam satu loop.
Salinan kode adalah sebagai berikut:
untuk (var i = 0; i <10; i ++) {
setTimeout (function () {
console.log (i);
}, 1000);
}
Kode di atas tidak akan menghasilkan 0 hingga 9, tetapi akan menghasilkan 10 kali terus menerus.
Anonimitas di atas akan menyimpan referensi ke variabel i. Ketika fungsi Console.log dipanggil untuk memulai output, ini adalah loop yang telah berakhir, dan variabel I sudah 10.
Untuk menghindari kesalahan di atas, kita perlu membuat salinan variabel I nilai setiap kali kita loop.
Hindari kesalahan kutipan
Untuk menyalin nilai variabel dalam loop, cara terbaik adalah dengan menambahkan fungsi anonim ke lapisan luar dan segera menjalankannya.
Salinan kode adalah sebagai berikut:
untuk (var i = 0; i <10; i ++) {
(function (e) {
setTimeout (function () {
console.log (e);
}, 1000);
})(Saya);
}
Fungsi anonim eksternal ini mengambil variabel loop I sebagai parameter pertama dan menyalin nilainya ke parameternya sendiri e.
Fungsi anonim eksternal melewati parameter E ke SetTimeout, sehingga SetTimeout memiliki referensi ke parameter e. Selain itu, nilai parameter ini E tidak akan berubah karena perubahan loop eksternal.
Ada cara lain untuk mencapai efek yang sama, yaitu mengembalikan fungsi anonim dalam fungsi anonim di SetTimeout:
Salinan kode adalah sebagai berikut:
untuk (var i = 0; i <10; i ++) {
setTimeout ((function (e) {
return function () {
console.log (e);
}
}) (i), 1000)
}
Selain itu, itu juga dapat dicapai melalui metode BIND.
Salinan kode adalah sebagai berikut:
untuk (var i = 0; i <10; i ++) {
setTimeout (console.log.bind (konsol, i), 1000);
}
Di akhir artikel, mari kita ringkas:
(1) Penutupan adalah prinsip desain. Ini menyederhanakan panggilan pengguna dengan menganalisis konteks, memungkinkan pengguna untuk mencapai tujuannya tanpa menyadarinya;
(2) Artikel online utama tentang analisis penutupan sebenarnya bertentangan dengan prinsip penutupan. Jika Anda perlu mengetahui detail penutupan yang akan digunakan dengan baik, penutupan ini adalah kegagalan desain;
(3) Cobalah untuk belajar sesedikit mungkin.