文档章节

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

村北稻山
 村北稻山
发布于 2016/11/27 23:46
字数 722
阅读 6
收藏 0
点赞 0
评论 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

这一次,我们换种姿势学习 javascript

前言 《你不知道的 javascript》是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途。本书介绍了该系列的两个主题:“作用...

程序员解决师 ⋅ 05/29 ⋅ 0

闭包详解二:JavaScript中的高阶函数

注:文章最末尾有个人公众号二维码,会分享更多技术文章等,敬请关注 本文讲解的高阶函数是之前讲解的闭包的续集,所以在学习高阶函数之前,一定要确保对闭包以及作用域的概念已经有了解: ...

lce_shou ⋅ 06/05 ⋅ 0

深入学习JavaScript函数

前言: 函数对于任何一门语言来说都是核心的概念,通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。而JavaScript中最好的特性就是它对函数的实现。它几乎无所不能。但...

云中玉卷 ⋅ 05/02 ⋅ 0

JavaScript核心概念归纳整理

原文出处: 熊俊漉 JavaScript语言本身是一个庞大而复杂的知识体系,复杂程度不低于任何一门后端语言,本文针对JavaScript语言的核心概念进行简单的梳理,对应的每个知识点仅仅点到为止,不作...

音乐宇Code ⋅ 05/27 ⋅ 0

【译】【nodeschool】【scope-chains-closures】作用域

作用域链与闭包工作 作用域,作用域链,闭包以及垃圾回收它们有一个共同点:那就是它们通常都是手动执行的。闭包实际上是如何工作的?垃圾回收在什么时候发生?作用域链到底是什么? 通过这次...

小草先森 ⋅ 05/14 ⋅ 0

深入理解闭包之前置知识→作用域与词法作用域

前言 这两天刚好和朋友讨论到闭包,这个JavaScript中的“神兽”,很多同学会觉得闭包这玩意太闹心了,怎么着都理解不了...其实刚接触JavaScript的时候我也是这样的。 但是呢,闭包却非常重要...

lce_shou ⋅ 05/16 ⋅ 0

深入理解闭包之前置知识---作用域与词法作用域

前言 这两天刚好和朋友讨论到闭包,这个JavaScript中的“神兽”,很多同学会觉得闭包这玩意太闹心了,怎么着都理解不了...其实刚接触JavaScript的时候我也是这样的。 但是呢,闭包却非常重要...

iceman_dev ⋅ 05/15 ⋅ 0

【译】JavaScript进阶 从实现理解闭包

来源于 现代JavaScript教程 闭包章节 中文翻译计划 本文很清晰地解释了闭包是什么,以及闭包如何产生,相信你看完也会有所收获 关键字 Closure 闭包 Lexical Environment 词法环境 Environm...

ssshooter ⋅ 06/04 ⋅ 0

四月前端知识集锦(每月不可错过的文章集锦)

目前自己组建的一个团队正在写一份面试图谱,将会在七月中旬开源。内容十分丰富,第一版会开源前端方面知识和程序员必备知识,后期会逐步写入后端方面知识。因为工程所涉及内容太多(目前已经...

夕阳 ⋅ 05/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据工程师需要精通算法吗,要达到一个什么程度呢?

机器学习是人工智能的一个重要分支,而机器学习下最重要的就是算法,本文讲述归纳了入门级的几个机器学习算法,加大数据学习群:716581014一起加入AI技术大本营。 1、监督学习算法 这个算法由...

董黎明 ⋅ 46分钟前 ⋅ 0

Kylin 对维度表的的要求

1.要具有数据一致性,主键值必须是唯一的;Kylin 会进行检查,如果有两行的主键值相同则会报错。 2.维度表越小越好,因为 Kylin 会将维度表加载到内存中供查询;过大的表不适合作为维度表,默...

无精疯 ⋅ 49分钟前 ⋅ 0

58到家数据库30条军规解读

军规适用场景:并发量大、数据量大的互联网业务 军规:介绍内容 解读:讲解原因,解读比军规更重要 一、基础规范 (1)必须使用InnoDB存储引擎 解读:支持事务、行级锁、并发性能更好、CPU及...

kim_o ⋅ 52分钟前 ⋅ 0

代码注释中顺序更改 文件读写换行

`package ssh; import com.xxx.common.log.LogFactory; import com.xxx.common.log.LoggerUtil; import org.apache.commons.lang3.StringUtils; import java.io.*; public class DirErgodic ......

林伟琨 ⋅ 今天 ⋅ 0

linux实用操作命令

参考 http://blog.csdn.net/qwe6112071/article/details/50806734 ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件-A 同-a,但不列出"."和"...

简心 ⋅ 今天 ⋅ 0

preg_match处理中文符号 url编码方法

之前想过直接用符号来替换,但失败了,或者用其他方式,但有有些复杂,这个是一个新的思路,亲测可用 <?php$str='637朗逸·超速新风王(300)(白光)'; $str=iconv("UTF-8","GBK",$s...

大灰狼wow ⋅ 今天 ⋅ 0

DevOps 资讯 | PostgreSQL 的时代到来了吗 ?

PostgreSQL是对象-关系型数据库,BSD 许可证。拼读为"post-gress-Q-L"。 作者: Tony Baer 原文: Has the time finally come for PostgreSQL?(有删节) 近30年来 PostgreSQL 无疑是您从未听...

RiboseYim ⋅ 今天 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 今天 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 今天 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部