博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript中闭包(Closure)的探索(一)-基本概念
阅读量:6131 次
发布时间:2019-06-21

本文共 2185 字,大约阅读时间需要 7 分钟。

由于我是做web开发的,在项目中经常使用javascript。对js的闭包特性早有耳闻,趁着不是很忙自己研究了一下。

通过从网络上的查找,了解到javascript的闭包特性,总结了一下,不足之处希望大家不吝指教!

1.Closure的基本概念(摘抄如下):

“闭包”是一个表达式(一般是函数),它具有自由变量以及绑定这些变量的环境(该环境“封闭了”这个表达式)。

闭包,就是封闭了外部函数作用域中变量的内部函数。但是,如果外部函数不返回这个内部函数,闭包的特性无法显现。

如果外部函数返回这个内部函数,那么返回的内部函数就成了名副其实的闭包。此时,闭包封闭的外部变量就是自由变量,而由于该自由变量存在,外部函数即便返回,其占用的内存也得不到释放。

2.以一个小问题为例解释一下闭包的特性:

要求:给页面上的一系列按钮绑定带有不同参数的函数。

代码(为说明问题简化了代码):

 
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>
JsClosure
</
title
>
<
script
type
="text/javascript"
>
function
initBtnClick() {
for
(
var
i
=
1
; i
<
6
; i
++
) {
var
btn
=
document.getElementById(
"
button
"
+
i);
btn.onclick
=
function
() {
alert(i);
};
}
}
</
script
>
</
head
>
<
body
>
<
input
type
="button"
value
="closureTest"
onclick
="initBtnClick()"
/>
<
input
type
="button"
value
="button1"
id
="button1"
/>
<
input
type
="button"
value
="button2"
id
="button2"
/>
<
input
type
="button"
value
="button3"
id
="button3"
/>
<
input
type
="button"
value
="button4"
id
="button4"
/>
<
input
type
="button"
value
="button5"
id
="button5"
/>
</
body
>
</
html
>
 

现象:首先点击“closureTest”按钮给其他按钮绑定事件,然后点击其他五个按钮发现alert出来的值全是6。与预期的1,2,3,4,5相差甚远!

按闭包的定义分析现象:在给按钮绑定事件时使用的匿名函数(即封闭了外部函数作用域中变量的内部函数),但是由于外部函数initBtnClick没有返回此匿名函数,所以闭包没有起作用(即如果外部函数不返回这个内部函数,闭包的特性无法显现)。匿名函数封闭的外部变量(即i)没有成为自由变量,内存被释放,最终只保留了循环的最后一个值6。

根据分析改进initBtnClick函数,使其形成一个真正的闭包:

 
function
initBtnClick() {
for
(
var
i
=
1
; i
<
6
; i
++
) {
var
btn
=
document.getElementById(
"
button
"
+
i);
btn.onclick
=
function
(j) {
return
function
() {
alert(j);
}
} (i);
}
}

再次点击“closureTest”按钮给其他按钮绑定事件,然后点击其他五个按钮发现依次alert1,2,3,4,5。与预期的结果相同。

现象分析:通过执行外部的匿名函数(function(j))返回内部的匿名函数function(){alert(j);}形成真正的闭包(即如果外部函数返回这个内部函数,那么返回的内部函数就成了名副其实的闭包)。匿名函数(function(j))传入的参数i就成了自由变量,内存不会被释放(即闭包封闭的外部变量就是自由变量,而由于该自由变量存在,外部函数即便返回,其占用的内存也得不到释放)。

改进后的代码如下,为了清晰一些将内部匿名函数封装了一下:

 
function
displayNum(inputNum) {
return
function
() {
alert(inputNum);
};
}
function
initBtnClick() {
for
(
var
i
=
1
; i
<
6
; i
++
) {
var
btn
=
document.getElementById(
"
button
"
+
i);
btn.onclick
=
displayNum(i);
}
}

本例只是简单的介绍了一下js的闭包,只是希望大家能对闭包有个直观点的了解。

本文转自wang_yb博客园博客,原文链接:http://www.cnblogs.com/wang_yb/archive/2010/05/04/1727503.html,如需转载请自行联系原作者

你可能感兴趣的文章
NGUI Label Color Code
查看>>
.NET Core微服务之基于Polly+AspectCore实现熔断与降级机制
查看>>
vue组件开发练习--焦点图切换
查看>>
浅谈OSI七层模型
查看>>
Webpack 2 中一些常见的优化措施
查看>>
移动端响应式
查看>>
python实现牛顿法求解求解最小值(包括拟牛顿法)【最优化课程笔记】
查看>>
js中var、let、const的区别
查看>>
腾讯云加入LoRa联盟成为发起成员,加速推动物联网到智联网的进化
查看>>
从Python2到Python3:超百万行代码迁移实践
查看>>
Windows Server已可安装Docker,Azure开始支持Mesosphere
查看>>
简洁优雅地实现夜间模式
查看>>
react学习总结
查看>>
微软正式发布PowerShell Core 6.0
查看>>
Amazon发布新的会话管理器
查看>>
InfoQ趋势报告:DevOps 和云计算
查看>>
舍弃Python,为什么知乎选用Go重构推荐系统?
查看>>
在soapui上踩过的坑
查看>>
MySQL的字符集和字符编码笔记
查看>>
ntpd同步时间
查看>>