JavaScript 闭包LOGIN

JavaScript 闭包

什么是闭包

 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的特点:

  1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。

  2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

  简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。


闭包的几种写法和用法

第一种写法

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>php中文网(php.cn)</title> 
    <script type="text/javascript">  
          function Circle(r) {  
            this.r = r;  
           }  
           Circle.PI = 3.14159;  
           Circle.prototype.area = function() {  
             return Circle.PI * this.r * this.r;  
           }  
          var c = new Circle(1.0);     
           alert(c.area());   
    </script>  
</head>  
<body>  
</body>
</html>

这种写法没什么特别的,只是给函数添加一些属性。

第二种写法

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>php中文网(php.cn)</title> 
    <script type="text/javascript">  
       var Circle = function() {  
         var obj = new Object();  
         obj.PI = 3.14159;  
        obj.area = function( r ) {  
             return this.PI * r * r;  
           }  
            return obj;  
         }  
        var c = new Circle();  
         alert( c.area( 1.0 ) );  
    </script>  
</head>  
<body>  
</body>
</html>

这种写法是声明一个变量,将一个函数当作值赋给变量。

第三种写法

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>php中文网(php.cn)</title> 
    <script type="text/javascript">  
       var Circle = new Object();  
            Circle.PI = 3.14159;  
            Circle.Area = function( r ) {  
             return this.PI * r * r;  
            }  
           alert( Circle.Area( 1.0 ) );  
    </script>  
</head>  
<body>  
</body>
</html>

这种方法最好理解,就是new 一个对象,然后给对象添加属性和方法。

第四种写法

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>php中文网(php.cn)</title> 
    <script type="text/javascript">  
         var Circle={  
           "PI":3.14159,  
            "area":function(r){  
               return this.PI * r * r;  
              }  
           };  
          alert( Circle.area(1.0) );  
    </script>  
</head>  
<body>  
</body>
</html>

这种方法使用较多,也最为方便。var obj = {}就是声明一个空的对象


Javascript闭包的用途 

事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。

1、匿名自执行函数

2、结果缓存

3、封装

4、实现类和继承


JavaScript 内嵌函数

所有函数都能访问全局变量。  

实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。

JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。

该实例中,内嵌函数 plus() 可以访问父函数的 counter 变量:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<p id="demo">0</p>
<script>
document.getElementById("demo").innerHTML = add();
function add() {
var counter = 0;
    function plus() {counter += 1;}
    plus();    
    return counter; 
}
</script>
</body>
</html>

如果我们能在外部访问 plus() 函数,这样就能解决计数器的困境。

我们同样需要确保 counter = 0 只执行一次。

这里就需要闭包。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
function myFunction(){
    document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>

实例解析

变量 add 指定了函数自我调用的返回字值。

自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。

add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。

这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。

计数器受匿名函数的作用域保护,只能通过 add 方法修改。

闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

下一节
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> <script type="text/javascript"> function buildFunctions(){ var funcArr = []; for(var i = 0; i < 3; i++){ funcArr.push((function(j){ return function(){ console.log(j); }; }(i))); } return funcArr; } var fs = buildFunctions(); fs[0](); //0 fs[1](); //1 fs[2](); //2 </script> </head> <body> <p>请在浏览器中点击 F12 来观察结果</p> </body> </html>
提交重置代码
章节课件