寫了幾個小例子揭示JS中閉包的本質,適合本身運行後分析。html
HTML文件jquery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test</title> <script src="lib/jquery-3.1.0.js"></script> <script src="closure_example.js"></script> </head> <body> <button>0</button> <button>1</button> <button>2</button> <button>3</button> <button>4</button> <button>5</button> <button style="display:none" class="hide">什麼是閉包</button> </body> </html>
JS代碼閉包
$(function () { /* 給6個按鈕綁定事件,點擊打印按鈕的序號 */ for (var i = 0; i < 6; i++) { $('button').eq(i).on('click', function () { console.log(i); }); } /* 解決方案一:借用DOM元素的屬性存儲序號i */ for (var i = 0; i < 6; i++) { $('button').eq(i).attr('i', i).on('click', function () { console.log($(this).attr('i')); }); } /* 解決方案二:利用IIFE將i做爲參數傳遞給內部函數 */ for (var i = 0; i < 6; i++) { (function (i) { $('button').eq(i).on('click', function () { console.log(i); }); })(i); } /* 錯誤方案:IIFE使用位置錯誤 */ for (var i = 0; i < 6; i++) { $('button').eq(i).on('click', function () { (function (i) { console.log(i); })(i); }); } /* 解決方案三:利用IIFE所創造的「塊級做用域」,將i賦值給局部變量 */ for (var i = 0; i < 6; i++) { (function () { var temp = i; $('button').eq(temp).on('click', function () { console.log(temp); }); })(); } /* 什麼是閉包? */ function closure() { var i = 0; return function fun() { i++; console.log(i); } } var foo = closure(); foo(); foo(); foo(); var bar = closure(); bar(); bar(); bar(); $('.hide').show().on('click', foo) });