JavaScript闭包原理分析

写了几个小例子揭示JS中闭包的本质,适合自己运行后分析。


HTML文件  

<!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)

});