当前位置:首页 > 开发 > Web前端 > JavaScript > 正文

浅说JavaScript闭包

发表于: 2010-12-31   作者:bardo   来源:转载   浏览次数:
摘要: 什么是闭包:闭包是一个被闭合作用域限制的函数类型的变量。这样说,似乎太抽象。但至少我们清楚了三点:闭包肯定存在于一个变量中,第二点,此变量类型是函数。第三点:此函数被一闭合作用域限制。看一下实例:1、闭包依赖于函数内嵌套函数的结构,即首先要有局部作用域,不能是全局作用域。如下例: var x = "global"; function f() { var x =

什么是闭包:闭包是一个被闭合作用域限制的函数类型的变量。
这样说,似乎太抽象。但至少我们清楚了三点:闭包肯定存在于一个变量中,第二点,此变量类型是函数。第三点:此函数被一闭合作用域限制。
看一下实例:
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会导致内存溢出。

 

 

 

 

 

 

浅说JavaScript闭包

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
1 什么是闭包? 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的表达式(通常这是一
最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标 学好一门,学精通一门。不求
官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而
一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两
一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两
今天我们从内存结构上来讲解下 javascript中的闭包概念。 闭包:是指有权访问另外一个函数作用域中
最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业。对于初学者
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面
什么是闭包 闭包是指有权访问另一个函数作用域中的变量的函数(有点拗口吧),简单点就是在一个函数
作为第一次接触闭包,就将自己的理解及查询相关信息进行总结,在谈论闭包之前,先了解几个相关知识
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号