Javascript中闭包(Closure)的探索(一)-基本概念

由于我是做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的闭包,只是希望大家能对闭包有个直观点的了解。

posted @   wang_yb  阅读(689)  评论(2编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示