Dalam JavaScript, fungsi boleh dianggap sebagai sejenis data, yang boleh diberikan kepada pembolehubah dan bersarang dalam fungsi lain.
var fun = function(){ console.log("平底斜"); }
function fun(){ var n=10; function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //11
Mari ubah suai sedikit kod kedua di atas:
var n=10; function fun(){ function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //12
Adakah anda melihat perbezaannya? Jika anda tidak dapat memahami hasil pelaksanaan kod, sila baca catatan blog sebelum ini untuk mendapatkan penjelasan tentang skop dan rantaian skop JavaScript.
Pembolehubah n dalam kod di atas ialah pembolehubah global dan boleh ditetapkan semula pada bila-bila masa tanpa memanggil fungsi keseronokan. Untuk mengelakkan pembolehubah n daripada tercemar, atau untuk mengurangkan pencemaran pembolehubah global, kita perlu meletakkan n dalam fungsi sebagai pembolehubah tempatan.
function fun(){ var n=10; function son(){ n++; console.log(n); } son(); } fun(); //11 fun(); //11
Jika kita boleh terus memanggil fungsi anak secara global, kita boleh mencapai kesan yang diingini. Fungsi anak kini wujud sebagai pembolehubah tempatan Untuk mengaksesnya secara global, biasanya terdapat dua kaedah:
Salah satunya adalah untuk memberikan nilai kepada pembolehubah global
var a; function fun(){ var n=10; a = function son(){ n++; console.log(n); } } fun(); //son() a(); //11 a(); //12
Lainnya ialah menggunakan return untuk mengembalikan nilai
function fun(){ var n=10; return function son(){ n++; console.log(n); } } var a=fun(); a(); //11 a(); //12
Fungsi son() di atas ialah penutupan, semua fungsi boleh dianggap sebagai penutup. Penutupan ialah fungsi yang boleh mengakses pembolehubah dalam skop fungsi luar.
var a; function fun(){ var n=10; a = function son(){ n++; console.log(n); } return a(); } fun(); //11 a(); //12 a(); //13 fun(); //11 a(); //12 a(); //13
Ia masih kod di atas Mari kita ubah suainya sedikit dan lihat hasil pelaksanaan Ini kerana pembolehubah n dimulakan setiap kali fungsi fun() dilaksanakan.
Kelebihan penutupan adalah untuk mengurangkan pembolehubah global, mengelakkan pencemaran global dan menyimpan pembolehubah tempatan dalam ingatan. Tetapi ini adalah kelebihan dan kelemahan Jika terdapat terlalu banyak penutupan dalam sekeping kod, ia boleh menyebabkan kebocoran memori. Memandangkan pembolehubah tempatan dalam penutupan tidak akan dikitar semula oleh mekanisme pengumpulan sampah, ia perlu ditetapkan secara manual kepada null (mengenai kebocoran memori, topik berasingan akan dibuka kemudian)