什么是闭包:闭包是一个被闭合作用域限制的函数类型的变量。
这样说,似乎太抽象。但至少我们清楚了三点:闭包肯定存在于一个变量中,第二点,此变量类型是函数。第三点:此函数被一闭合作用域限制。
看一下实例:
1、闭包依赖于函数内嵌套函数的结构,即首先要有局部作用域,不能是全局作用域。如下例:
var x = "global";
function f() {
var x = "local";
function g() {
alert(x);
}
g();
}
f(); // Calling this function displays "local"
但这一结构只是让函数与变量拥有局部作用域。要产生闭包,还需要另一点。
2、闭包产生,需要的是函数中返回函数。如果,返回函数中用到外部函数内的变量,这里返回的不是函数本身,而是返回的闭包。下例是抛物线方程:
function parabola(a,b,c){
return function (x){
return a*x*x+b*x+c;
}
}
var p1=parabola(3,4,5);
alert (p1(15));
从此例可见,返回的不仅是一个函数,实际是返回的此函数的环境,即此函数所在外部环境的一个封闭的包——闭包。
由此我们也可以看出,第一个例子,只是显示了局部作用域。因为,内部函数是在外部调用时立即运行了。但如果内部函数返回,则会带出一个闭包。
闭包与逃脱:
上面所说的,内部函数作为变量返回。这就是闭包的逃脱(逃脱一词记得是在《精通JAVASCRIPT》一书中用到。)return一个函数,是一种逃脱方法。但也可以使用全局变量等于一个内部函数的作法。
现举例说明:我们有以下HTMLL
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<form id="form1" method="post" action="">
<input type="button" id="b1" value="按钮1" >
<input type="button" id="b2" value="按钮2">
<input type="button" id="b3" value="按钮3">
</form>
</body>
</html>
并且以下JS脚本
<script language="JavaScript" type="text/JavaScript">
function myShow(i){
alert(i);
}
for (i=1;i<4; i++){
//不使用闭包,这里就无法实现。因为没有闭包,i的上下文已不存在,所以,结果是.udefined
document.getElementById('b'+i).onmouseup = function(){myShow(i)};
}
</script>
现在我们使用普通的闭包结构:
<script language="JavaScript" type="text/JavaScript">
function myShow(i){
alert(i);
}
function keepShow(i){
var k=i; //存入闭包的变量中,产生闭包
//赋值模式实现闭包逃脱
document.getElementById('b'+k).onmouseup = function(){
myShow(k); //使用闭包中保存的变量
}
}
for (i=1;i<4; i++){
//使用普通闭包结构,改用闭包以后,我们实现了我们所要的功能。
keepShow(i);
}
</script>
前一篇文章《你了解javascript中的()吗?》中,我们提到了自动运行函数,亦或也称为模块闭合结构。这是闭包中最常用的结构。因为,用此结构,我们就可以直接使用匿名函数,而不需要定义相关函数名。
以下是使用模块闭合结构的闭包:
<script language="JavaScript" type="text/JavaScript">
function myShow(i){
alert(i);
}
for (i=1;i<4; i++){
//便用自动运行函数闭包结构
(function() { //把全局的放到闭包中,全局赋值式逃脱
var index = i; //外部参数存入外层函数局部变量
//内层函数访问外层的本地变量
document.getElementById('b'+i).onmouseup = function(){myShow(index)};
})();
}
</script>
以下是另一种结构:
<script language="JavaScript" type="text/JavaScript">
function myShow(i){
alert(i);
}
for (i=1;i<4; i++){
//便用自动运行函数闭包结构。使用return函数式逃脱。
document.getElementById('b'+i).onmouseup = (function (i){ //使用外层形参
return function(){myShow(i)}; //内层函数访问外层形参
})(i);
}
</script>
我们可以看出,赋值全局式逃脱,一般均可以改成return函数式逃脱,所以, return函数式逃脱被称为标准结构。程序中应当尽可能采取这样的方式编写代码。这样,能使代码可读,易读。这主要是因为,被操作的全局对象,不会进入闭包结构中。
闭包的程序机制:嵌套函数结构中,当外部函数调用完成后,外部函数的局部变量因返回值是内部函数,从而不会被销毁,而是随内部函数持续存在。并作为一个外包装连同返回的内部函数一同返回。
闭包注意事项:最好不要在闭包中使用Function对象,因为它优先读取全局变量。
不要自己用闭包操作DOM,因为IE的BUG会导致内存溢出。
分享到:
相关推荐
UEFIBIOS浅说 本文将从UEFI BIOS浅说 pptx文件中提炼出重要的知识点,以下是详细的解释: 一、BIOS 的概念和功能 BIOS(Basic Input/Output System,基本输入输出系统)是电脑中的一组固化程序,提供最低级的硬件...
根据提供的文件信息,我们可以推断出该文档主要讨论了狭义相对论与广义相对论的基本概念和发展历程。虽然部分内容缺失,但通过标题、描述以及已知的信息,我们可以概述狭义相对论与广义相对论的主要知识点。...
狭义相对论与广义相对论是现代物理学的基石之一,由阿尔伯特·爱因斯坦提出和发展。本文将从给定的文件标题、描述、标签以及部分内容出发,深入探讨狭义相对论与广义相对论的核心概念及其背后的物理意义。...
海典H1自定义事件框架浅说 1、窗口概述 2 2、窗口相关事件 3 1、打开窗口 3 key事件 4 timer事件 4 2、保存数据 4 1、 pfc_begintran 4 3、 pfc_endtran 4 4、 Pfc_save 4 3、关闭窗口 4 3、数据窗口事件 5 添加主...
浅说顾客满意度.ppt
浅说元代的监察制度.pdf
科技论文写作浅说。本人写的PPT文档。根据张孙伟老师的书,编写。为何把“科技论文写作”作为一门独立的课程? 要准确地把科技成果记录下来,应该规范地按照科技论文的要求进行。 科技论文的写作,在形式上有一...
浅说信息时代的媒体.pdf
我国高压电网浅说设计说明.doc
初中语文语文论文语感素质培养浅说
系统论、信息论、控制论是现代科学技术中的三个重要理论,它们诞生于20世纪中叶,是现代科学方法论的重要组成部分。本书旨在向读者普及这三个理论的基本知识,特别适合具有一定文化程度的普通读者。...
很抱歉,但根据您提供的信息,标题和描述中的"深化浅说长路慢走[路要慢走的散文].rar"以及压缩包内的文件"深化浅说长路慢走[路要慢走的散文].pdf"似乎与IT行业知识并无直接关联。它们更可能属于文学或哲学类的内容,...
博弈论与信息经济学浅说.docx
博弈论与信息经济学浅说.doc
浅说从词到文章的组织选录.doc
身边的博弈论:博弈论与信息经济学浅说.docx
混沌理论必学,以浅显的语言阐述了混沌理论的基础及应用,是十分难能可贵的学习资料。