文档章节

《你不知道的JavaScript(上卷)》读书总结之闭包

村北稻山
 村北稻山
发布于 2016/11/27 23:46
字数 722
阅读 6
收藏 0

闭包的“官方”解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。这种文字上的定义确实不好理解,也不知道它说的函数是哪个函数,但如果我们记住了闭包的两种情况,和闭包的作用,或许对闭包会有更好的理解,而不必在意于它的文字定义。

闭包的作用:

①为了突破作用域(对于作用域上篇有介绍),使得我们好像在函数外部也能访问在函数内部定义的局部变量,注意这里用了“好像”一词,因为闭包并不能让我们真正做到在函数外部直接使用函数内部定义的局部变量,但是可以通过某些方法间接使用,而为什么要在函数内部定义变量呢,而不直接在函数外部定义,是为了形成模块,防止变量污染。

    function fn1(){
        var a=2;
        function fn2(){
            console.log(a);
        }
        return fn2;
    }
    var fn3=fn1();
    fn3(); // 2

上面这段代码,使得函数fn2在函数fn1外部得到了执行,是因为在fn1内部有个return,将fn2返回了。

    var foo=(function CoolModule(){
        var something = "cool";
        var another = [1,2,3];
        function doSomething(){
            console.log(something)
        }
        function doAnother(){
            console.log(another.join("!"))
        }
        return{
            doSomething:doSomething,
            doAnother:doAnother
        }
    })();
    foo.doSomething();  // cool
    foo.doAnother();    // 1!2!3

这段代码也一样,使得局部变量 doSomething和doAnother这两个函数在外部都得到了执行。这个函数形成模块,只有一个foo变量暴露在全局作用域中。

②为了使得变量一直保存在内存中,不被垃圾回收机制回收。看下面的代码:

    function outerFun()
    {
        var a=0;
        function innerFun()
        {
            a++;
            console.log(a);
        }
        return innerFun;
    }
    var obj=outerFun();
    obj();  // 1
    obj();  // 2
    var obj2=outerFun();
    obj2();  // 1
    obj2();  // 2

以上的闭包应用情况中都有一个return,将函数作为返回值,这就是闭包的一种应用情况,还有一种就是将变量作为参数传递。

    for(var i=1;i<=5;i++){
        setTimeout(function timer(){
            console.log(i)
        },i*1000)
    }

可能你会认为这段代码的输出结果为1-5,但是程序的结果跟我们的预期总是不一样,正确结果为输出五次6,这是因为延迟函数的回调会在循环结束时才执行,所以那时i已经等于6。可以将代码改进如下,结果为1-5。

    for(var i=1;i<=5;i++){
        (function (j){
            setTimeout(function timer(){
                console.log(j)
            },j*1000)
        })(i)
    }

这就是闭包的作用和应用情况,至于闭包的第二种用法(本文最后一个代码)与前面所介绍的闭包作用有什么关系我自个也还不是很清楚,可以一起讨论。

© 著作权归作者所有

共有 人打赏支持
村北稻山
粉丝 9
博文 15
码字总数 9091
作品 0
昌平
【前端工程师手册】JavaScript作用域拾遗

【前端工程师手册】JavaScript作用域拾遗 昨天总结了一些作用域的知识【前端工程师手册】JavaScript之作用域,但是发表完发现忘记了一些东西,今天拾个遗。 昨天说到了JavaScript中没有块级作...

推荐码发放
05/17
0
0
记一次前端大厂面试 | 掘金技术征文

前言 最近参加了几家杭州大厂的面试,顺利的拿到了自己心仪的offer,积累了一些高频面试题,记录给有需要的同学们。我把面试题归纳整理分为两类,一种是基础试题: 主要考察前端技基础是否扎实...

程序员解决师
09/11
0
0
[转] Javascript闭包

资料: http://kb.cnblogs.com/page/110782/ 当function里嵌套function时,内部的function可以访问外部function里的变量。 function foo(x) {var tmp = 3;function bar(y) { }bar(10);} foo(......

庸夫俗子
2011/11/18
0
0
图解Javascript上下文与作用域

本文尝试阐述Javascript中的上下文与作用域背后的机制,主要涉及到执行上下文(execution context)、作用域链(scope chain)、闭包(closure)、等概念。 >> 原文 << Execution context 执...

rainyear
2015/07/06
0
7
JavaScript 需要掌握的知识

1.不仅仅是面试,JavaScript 开发者都应该知道的十个概念(https://my.oschina.net/editorial-story/blog/1529543) 2. 深入理解javascript原型和闭包(完结)(http://www.cnblogs.com/wangfup...

IT追寻者
2016/06/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

70.shell的函数 数组 告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析 20.16/20.17 shell中的函数: ~1. 函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段...

王鑫linux
今天
2
0
分布式框架spring-session实现session一致性使用问题

前言:项目中使用到spring-session来缓存用户信息,保证服务之间session一致性,但是获取session信息为什么不能再服务层获取? 一、spring-session实现session一致性方式 用户每一次请求都会...

WALK_MAN
今天
6
0
C++ yield()与sleep_for()

C++11 标准库提供了yield()和sleep_for()两个方法。 (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周...

yepanl
今天
4
0
Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)

这个系列一直没再写,很多原因,中间经历了换工作,熟悉项目,熟悉新团队等等一系列的事情。并发课题对于Java来说是一个又重要又难的一大块,除非气定神闲、精力满满,否则我本身是不敢随便写...

心中的理想乡
今天
45
0
shell学习之获取用户的输入命令read

在运行脚本的时候,命令行参数是可以传入参数,还有就是在脚本运行过程中需要用户输入参数,比如你想要在脚本运行时问个问题,并等待运行脚本的人来回答。bash shell为此提 供了read命令。 ...

woshixin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部