闭包(JavaScript)

Posted 减一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闭包(JavaScript)相关的知识,希望对你有一定的参考价值。

定义

先看看《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)的主要内容,如果未能解决你的问题,请参考以下文章

Spark闭包与序列化

JavaScript ---- 闭包(什么是闭包,为什么使用闭包,闭包的作用)

JavaScript 闭包(随笔)

javascript中的闭包

Javascript中的闭包

Javascript中的闭包(转载)