码迷,mamicode.com
首页 > 编程语言 > 详细

闭包(JavaScript)

时间:2017-12-15 19:34:27      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:ext   click   source   lis   记录   htm   进入   第2版   说明   

定义

先看看《JavaScript高级程序设计》(第3版)中对闭包的定义:

闭包是指一个有权访问另一个函数作用域中的变量的函数。

既然如此,那闭包它首先是一个函数,其次它还具备访问另一个函数作用域内变量的能力。

先做个铺垫

下面代码初衷:执行一个数组元素时输出该数组的下标值。

function F(){
    var arr = [],i;
    for(i=0;i<3;i++){
        arr[i] = function(){
            return i;
        }
    }
    return arr;
}
var arr = F();
console.log(arr[0]());//3
console.log(arr[1]());//3
console.log(arr[2]());//3

通过验证,发现以上代码并没有达到初衷。那么又是什么原因导致每次执行都会输出3呢?
原因是当执行完 var arr = F(); 的时候, i 已经从for循环递增到3了。所以当每次执行数组元素中的函数想输出该元素的下标时,总会输出3。

使用闭包解决上述问题

function F(){
    var arr = [],i;
    for(i=0;i<3;i++){
        arr[i] = (function(x){
            return x;
        })(i);
    }
    return arr;
}
var arr = F();
console.log(arr[0]());//0
console.log(arr[1]());//1
console.log(arr[2]());//2

对比一下,使用一个即时函数就可以解决问题。分析一下:第一个例子没有实现预期效果的原因是虽然创建了三个闭包,但是返回值只是 i 的引用,既然是引用,所以每次返回的都将是同一个值–3;  
同理,第二个例子能保存i值的原因是每次进入for循环后即时函数都创建了不用的局部变量,每次的局部变量则记录每次for循环的值,因此当执行数组元素函数时便能访问到不同的值。

常见的应用场景

下面代码初衷:点击一个div输出该div的类数组对象index值。

<html>
    <body>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <script type="text/javscript">
            var nodes = document.getElementsByTagName("div");
                for(var i =0;i<nodes.length;i++){
                    nodes[i].addEventListener("click",function(){
                       console.log(i);
                    });
                 }
        </script>
    </body>
</html>

再一次地,点击div依旧没有输出我们想要的结果。下面利用闭包来解决:

<html>
    <body>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <script type="text/javscript">
            var nodes = document.getElementsByTagName("div");
                for(var i =0;i<nodes.length;i++){
                    (function(x){
                        nodes[i].addEventListener("click",function(){
                            console.log(x);
                        });
                    })(i);
                };
        </script>
    </body>
</html>

文章说明

参考资料文献:《JavaScript高级程序设计》(第3版)

《JavaScript面向对象编程指南》(第2版)

水平有限,欢迎指正。

闭包(JavaScript)

标签:ext   click   source   lis   记录   htm   进入   第2版   说明   

原文地址:http://www.cnblogs.com/wuzhi123/p/8044504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!