Skop JavaScript dibatasi oleh fungsi dan fungsi yang berbeza mempunyai skop yang agak bebas. Pembolehubah global boleh diisytiharkan dan diakses di dalam fungsi, dan pembolehubah tempatan juga boleh diisytiharkan (menggunakan kata kunci var, parameter fungsi juga pembolehubah tempatan), tetapi pembolehubah tempatan dalaman tidak boleh diakses di luar fungsi:
function test() { var a = 0; // 局部变量 b = 1; // 全局变量 } a = ?, b = ? // a为undefined,b为1
Pembolehubah tempatan dengan nama yang sama akan mengatasi pembolehubah global, tetapi pada asasnya ia adalah dua pembolehubah tidak bersandar Perubahan dalam satu tidak akan menjejaskan yang lain:
a = 5; // 函数外a的值为5 function test() { var a = 4; // 函数内a的值为4 }(); a = ? // 函数外a的值仍为5,不受函数影响
Secara umumnya, selepas fungsi tamat, semua rujukan kepada pembolehubah dalaman fungsi berakhir, pembolehubah tempatan dalam fungsi akan dikitar semula, dan persekitaran pelaksanaan fungsi akan dikosongkan digunakan sebagai hasil pulangan fungsi, keadaan akan berubah:
function test(i) { var b = i * i; return function() { return b--; }; } var a = test(8); a(); // 返回值为64, 内部变量b为63 a(); // 返回值为63, 内部变量b为62
Apabila fungsi dalaman digunakan sebagai nilai pulangan, kerana rujukan kepada pembolehubah dalaman tidak berakhir selepas fungsi tamat, pembolehubah tempatan fungsi tidak boleh dikitar semula, dan persekitaran pelaksanaan fungsi itu dikekalkan, oleh itu membentuk kesan penutupan, yang boleh diluluskan Akses rujukan kepada pembolehubah dalaman yang harus dikitar semula.
Penutupan juga menjadikan pembolehubah tempatan fungsi "peribadi" pembolehubah, yang hanya boleh diakses melalui fungsi dalaman yang dikembalikan dan tidak boleh diubah dengan sebarang cara lain.
Oleh itu, penutupan boleh digunakan untuk mengekalkan pembolehubah tempatan dan melindungi pembolehubah.
Tanpa penutupan:
var a = []; // 假设a中包含5个元素 for (var i = 0, m = a.length; i < m; i++) { a[i].onclick = function(e) { return 'No. ' + i; }; } // 点击任何一个元素,返回值都是“No. 5”,因为i最后的值为5 使用闭包的情况: function test(i) { return function(e) { return 'No. ' + i; }; } var a = []; // 假设a中包含5个元素 for (var i = 0, m = a.length; i < m; i++) { a[i].onclick = test(i); } // 使用闭包维持局部变量,点击元素返回No. 0 ~ No. 4
Walaupun penutupan membawa kemudahan, ia juga membawa beberapa keburukan:
1. Kerumitan program meningkat dan ia menjadi lebih sukar untuk difahami
2. Mengganggu kutipan sampah biasa, penutupan yang kompleks juga boleh menyebabkan memori gagal dikitar semula dan ranap
3. Penutupan yang besar selalunya disertai dengan masalah prestasi
Oleh itu, penutupan hendaklah padat dan padat, bukannya besar dan kompleks, dan penggunaan penutupan berskala besar harus dielakkan. Kemunculan penutupan itu sendiri adalah pepijat dalam bahasa, tetapi ia kekal kerana fungsinya yang unik. Ia adalah cara tambahan, bukan fungsi utama.