定义:通俗讲,闭包是函数里面再定义一个函数,里层函数能访问到外层函数的布局变量,也就是说闭包是一个能访问外层函数布局变量的函数。常用情景有以下3种。
1.在window下有个全局变量a,在函数checkScope内部有个局部变量a。需求:在window下调用函数checkScope达到返回函数checkScope内部布局变量a的值。
<!DOCTYPE html
>
<
html
lang=
"en"
>
<
head
>
<
meta
charset=
"UTF-8"
>
<
meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<
meta
http-equiv=
"X-UA-Compatible"
content=
"ie=edge"
>
<
title
>Document
</
title
>
</
head
>
<
body
>
<
script
>
var
a =
'全局变量';
function
checkScope() {
var
a =
'局部变量'
function
f() {
return
a;
}
return
f();
}
console.
log(
checkScope());
//局部变量
<
/
script
>
</
body
>
</
html
>
2.页面有很多li元素,点击每一个li获取到该li标签的索引index。
如下代码并不能获取到点击的li的索引。
<!DOCTYPE html
>
<
html
lang=
"en"
>
<
head
>
<
meta
charset=
"UTF-8"
>
<
meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<
meta
http-equiv=
"X-UA-Compatible"
content=
"ie=edge"
>
<
title
>Document
</
title
>
</
head
>
<
body
>
<
ul
>
<
li
>这是第一个li
</
li
>
<
li
>这是第二个li
</
li
>
<
li
>这是第三个li
</
li
>
<
li
>这是第四个li
</
li
>
<
li
>这是第五个li
</
li
>
</
ul
>
<
script
>
var
li =
document.
getElementsByTagName(
'li');
for (
var
i =
0,
len =
li.
length;
i <
len;
i++) {
li[
i].
onclick =
function () {
console.
log(
i);
//5
}
}
<
/
script
>
</
body
>
</
html
>
使用闭包可以实现该需求
<!DOCTYPE html
>
<
html
lang=
"en"
>
<
head
>
<
meta
charset=
"UTF-8"
>
<
meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<
meta
http-equiv=
"X-UA-Compatible"
content=
"ie=edge"
>
<
title
>Document
</
title
>
</
head
>
<
body
>
<
ul
>
<
li
>这是第一个li
</
li
>
<
li
>这是第二个li
</
li
>
<
li
>这是第三个li
</
li
>
<
li
>这是第四个li
</
li
>
<
li
>这是第五个li
</
li
>
</
ul
>
<
script
>
var
li =
document.
getElementsByTagName(
'li');
for (
var
i =
0,
len =
li.
length;
i <
len;
i++) {
(
function (
i) {
li[
i].
onclick =
function () {
console.
log(
i);
}
}(
i))
}
<
/
script
>
</
body
>
</
html
>
3.提高函数性能,将结果保存,不需要将结果暴露在window的全局变量中。例如计算阶乘,如果以前有计算过,那么直接从以前的结果中获取,不需要重新计算。
<!DOCTYPE html
>
<
html
lang=
"en"
>
<
head
>
<
meta
charset=
"UTF-8"
>
<
meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<
meta
http-equiv=
"X-UA-Compatible"
content=
"ie=edge"
>
<
title
>Document
</
title
>
</
head
>
<
body
>
<
script
>
var
mult = (
function () {
var
cache = {};
var
calculate =
function () {
var
a =
1;
for (
var
i =
0,
len =
arguments.
length;
i <
len;
i++) {
a =
a *
arguments[
i];
}
return
a;
}
return
function () {
var
args =
Array.
prototype.
join.
call(
arguments,
',');
if (
args
in
cache) {
return
cache[
args];
}
return
cache[
args] =
calculate.
apply(
null,
arguments);
}
}())
<
/
script
>
</
body
>
</
html
>