闭包的定义

不用解释了,网上到处都是。简单的说:一个定义在函数内部的函数与包含它的外部函数构成了闭包,内部函数可以访问外部函数的变量,这些变量将一直保存在内存中,直到无法再引用这个内部函数

举个例子:

var vvval = 0;
function outerFun(i) {
    var vval = i;
    function innerFun() {
        var val = i;
        console.log("内部变量:"+val);
        console.log("外部变量:"+vval);
        console.log("全局变量:"+vvval);
        val++;
        vval++;
        vvval++;
    }
    return innerFun;
}
var testFun1 = outerFun(10);
testFun1();//内部变量:10 外部变量:10 全局变量:0
testFun1();//内部变量:10 外部变量:11 全局变量:1
var testFun2 = outerFun(20);
testFun2();//内部变量:20 外部变量:20 全局变量:2
testFun2();//内部变量:20 外部变量:21 全局变量:3

结论:
    val是innerFun()的局部变量,每次执行innerFun()都会重新赋值;
    vval是innerFun()的上一级变量,每次执行innerFun()的结果会保存在内存中,是outerFun()的局部变量,每次执行outerFun()都会重新赋值;
    vvval是innerFun()的上上一级变量,每次执行innerFun()的结果会保存在内存中,是outerFun()的上一级变量,每次执行outerFun()的结果会保存在内存中;
    
在JavaScript中,作用域只有全局作用域和函数级作用域两种,在下一级作用域中可以访问和修改上一级作用域的变量,在定义函数时,JS会自动维护一个作用域链,当前的局部作用域位于作用域链顶端,并可以依次向上回溯。闭包的实质就是延长了作用域链。

再举一个例子:

//若已经定义了10个<div>,现在想用循环给每个<div>根据序号绑定不同的事件
var i;
for(i=0;i<10;i++) {
    $("div:eq("+i+")").on("click",function() {
        console.log(i);
    });
}

然而,点击每个<div>输出结果均为10,这是因为i是全局变量,当改变i的值时,所有引用了它的函数都会受到影响。这时我们可以通过延长作用域链,为i的值保存一个副本,使它们之间不会互相影响:

var i;
for(i=0;i<10;i++) {
    function outer() {
        var vval = i;
        function inner() {
            console.log(vval);
        }
        $("div:eq("+vval+")").on("click",inner);
    }
    outer();
}

每循环一次就定义了一个外部函数outer()和一个内部函数inner(),因为inner()被绑定在<div>的click事件上,所以outer()中的变量没有在执行完之后就被释放,而是保存在内存中,最后需要执行一次outer(),初始化变量vval,当然你也可以使用自执行的匿名函数代替outer()。
解释一下:在JS中函数是可以重复定义的,只是执行的是最后一次定义的函数而已,例如:

function a() {
    console.log(1);
}
a();
function a() {
    console.log(2);
}
a();
//输出两个2

JS闭包,以及适用场景的更多相关文章

  1. js闭包之应用场景

    闭包的解释 当函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外执行,这时就产生了闭包 在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义 ...

  2. JS闭包的理解及常见应用场景

    JS闭包的理解及常见应用场景 一.总结 一句话总结: 闭包是指有权访问另一个函数作用域中的变量的函数 1.如何从外部读取函数内部的变量,为什么? 闭包:f2可以读取f1中的变量,只要把f2作为返回值, ...

  3. javascript深入理解js闭包

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

  4. js闭包

    先从闭包特点解释,应该更好理解. 闭包的两个特点: 1.作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态.2.一个闭包就是当一个函数返回时,一个没有释放资源的栈区. 其实上面两点可以合成一 ...

  5. 深入理解JS闭包

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

  6. 关于JS闭包,作者不详(转)

    说明:本文由两篇文章结合而成,系从他人笔记中转过来的, 具体作者不详.因为觉得不错,遂共享之.如有侵权,立删致歉. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变 ...

  7. js闭包之初步理解( JavaScript closure)

    闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解. 要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域, ...

  8. JS闭包的理解

    闭包的两个特点: 1.作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态.2.一个闭包就是当一个函数返回时,一个没有释放资源的栈区. 其实上面两点可以合成一点,就是闭包函数返回时,该函数内部 ...

  9. JS闭包(转载加整理)

    原文地址:http://www.jb51.net/article/24101.htm 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量 ...

  10. 理解js闭包(二)

    @(编程) 一.什么是闭包? 官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 相信很少有人能直接看懂这句话,因为他 ...

随机推荐

  1. Unity -JsonUtility的使用

    今天,为大家分享一下unity上的Json序列化,应该一说到这个词语,我们肯定会觉得,这应该是很常用的一个功能点:诚然,我们保存数据的时候,也许会用到json序列化,所以,我们有必要快速了解一下它的简 ...

  2. A GDI+ Based Character LCD Control

    This is a renew. A GDI+ Based Character LCD Control by Conmajia Character liquid crystal display (LC ...

  3. js里变量的作用域

    一.在js中,变量的定义并不是以代码块作为作用域的,而是以函数作为作用域.也就是说,如果变量是在某个函数中定义的,那么,它在函数以外的地方是不可见的.但是,如果该变量是定义在if或者for这样的代码块 ...

  4. Javascript中this关键字

    this 是谁调用的时候,指定的是谁,通俗一点讲就是,函数是谁执行是不是由其中一个对象点出来的那就是代表它, 比如执行对象a中b函数a.b();这个b函数中this代表a; 当换成var c=a.b; ...

  5. [ext4]03 磁盘布局 – Flexible group分析

    Flexible Block Groups (flex_bg),我称之为"弹性块组",是EXT4文件系统引入的一个feature. 所谓Flexible Block Groups, ...

  6. Angular简易分页设计(一):基本功能实现

    (首先声明本文来自博客园本人原创,转载请说明出处.欢迎关注:http://www.cnblogs.com/mazhaokeng/p/6752990.html) 之前网站的后台管理为了图快,把Jquer ...

  7. JS上了贼船

    本文纯属个人观点,没有引经据典,没有小心求证,just吐槽. 互联网的火热.移动web,带动了前端的飞速发展,js好像搭上了顺风车,身价水涨船高,如日中天. web前端是啥?html + css + ...

  8. 使用java API操作hdfs--拷贝部分文件到本地

    要求:和前一篇的要求正好相反.. 在HDFS中生成一个130KB的文件: 代码如下: import java.io.IOException; import org.apache.hadoop.conf ...

  9. 在Centos7 更改Docker默认镜像和容器的位置

    图片出处:https://bobcares.com/wp-content/uploads/docker-change-directory.jpg 一.Why? 通常,当你开始使用docker时,我们并 ...

  10. anjular中Service、Factory、Provider的使用与js中创建对象的总结

    在学习anjular中Service的使用时,发现和js中的创建对象的方式有一定的联系,所以总结了anjular中Service.Factory.Provider的使用方式与js创建对象的方式 一.先 ...