推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
RockHammer1947

[js] 大家聊聊 “闭包--Closure” 这个前端面试必问的永恒话题

  •  1
     
  •   RockHammer1947 · May 30, 2013 · 9351 views
    This topic created in 4910 days ago, the information mentioned may be changed or developed.
    这个永恒的话题一般是这样的:

    你是如何理解闭包的?什么情况下用闭包?

    我把闭包简单理解为,是函数返回后并没有释放内存中的资源。

    个人使用情况:
    1、封装,对象有私有属性或方法不希望外部直接访问的时候。
    2、缓存。
    3、类似独立的命名空间,避免变量污染到全局的情况,比如jQuery中
    (function( window , undefined ){

    })( window );

    另一考题,以下这两种写法的效果是一样的,为什么?

    var abc = (function(){
    return{.......};
    })();

    var abc = (function(){
    return{.......};
    }());
    30 replies  •  1970-01-01 08:00:00 +08:00
    typing
    typing
    May 30, 2013❤️4
    1
    对于Closure, 我现在印象最深的例子是这个:
    (对比注释行的区别)

    var callbacks = [];

    for(var i = 0; i < 3; ++i){
    // callbacks.push(function() {console.log(i);});

    callbacks.push(function(i){return function(){console.log(i);};}(i));
    }

    _.each(callbacks, function(f) {f();});
    Golevka
    Golevka
    May 30, 2013
    2
    没有释放内存中的资源什么的... 提到closure就不得不提到lexical scoping. 从实现角度来说确实是function definition和其所在的environment的绑定.
    xatest
    xatest
    May 30, 2013
    3
    为什么回复这个话题的都是ACG头像?。。。我来打破队形,对比一下函数和闭包:
    函数 = {抽象}
    闭包 = {抽象 + upvalue + env}
    otakustay
    otakustay
    May 30, 2013❤️2
    4
    我有一个专门说闭包的PPT,能把这个消化掉,我觉得闭包已经没有啥能难到你了
    https://skydrive.live.com/redir.aspx?resid=5AF9669191A78C07!197


    另外关于闭存回收的问题,我也有一个专门的博客总结过
    http://otakustay.com/about-closure-and-gc/
    yimity
    yimity
    May 30, 2013
    5
    我觉得要理解闭包首先要理解词法作用域,也就是函数执行时候查找变量等的过程,从函数最里面找,一直找到最外面的函数,如果内层函数没有定义的变量在外层找到,那么就可以说这个是闭包了。也由此可见,javascript 只要是函数,都可以形成闭包。

    私有变量,函数等
    防止全局变量污染
    然后就是保存某些变量的值,防止取得值是最终结果。
    初始化等。类似于常量。

    效果是一样的,先强制表达式,然后调用。
    otakustay
    otakustay
    May 30, 2013
    6
    @xatest 可见玩前端的都是些什么宅……
    RockHammer1947
    RockHammer1947
    OP
    May 30, 2013
    7
    @typing 亲,你想通过这个例子说明一个什么问题?
    RockHammer1947
    RockHammer1947
    OP
    May 30, 2013
    8
    @Golevka 虽然木有看懂,但是感觉很厉害的样子~
    otakustay
    otakustay
    May 30, 2013
    9
    @emohacker @typing 的那个是典型装饰lift问题,很坑的一个事,运行过你会明白的,而且确实是闭包特性导致
    switch
    switch
    May 30, 2013
    10
    (function( window , undefined ){

    })( window );
    這個不算是閉包,只是一個匿名函數自調用而已。
    RockHammer1947
    RockHammer1947
    OP
    May 30, 2013
    11
    @otakustay 学习
    RockHammer1947
    RockHammer1947
    OP
    May 30, 2013
    12
    @switch 我也挺纳闷的,之前在网上看有些人说是,看上去也有点像,就记下了,面试时是这么回答的,但是用闭包的概念去套,貌似是解释不通的。
    学艺不精,未得其精髓,深入学习中~
    Golevka
    Golevka
    May 30, 2013
    13
    @otakustay 不玩前端的路过, 并表示目前的工作比较偏硬件...
    @emohacker 关于lexical scoping和closure的关系5L的解释就很易懂了. SICP ch3对此也有涉及, 并且也是用的带upward的模型.
    RockHammer1947
    RockHammer1947
    OP
    May 30, 2013
    14
    @xatest 各种宅,哈哈哈
    xatest
    xatest
    May 30, 2013❤️1
    15
    我也不玩前端的,平时用到闭包最多的是写lua,给篇专门讲闭包的文章,举了各种语言(包括js)的例子:
    https://www.ibm.com/developerworks/cn/linux/l-cn-closure/
    RockHammer1947
    RockHammer1947
    OP
    May 30, 2013
    16
    @switch 可是通过 @yimity 5楼的回答,纠其根源。。。那个匿名函数的立即执行貌似又算是闭包。。。我还是有点不清晰
    renyuan1985
    renyuan1985
    May 30, 2013
    17
    @switch 恩是的,我也这样理解的,不知道我理解的闭包对不对http://renyuanz.com/javascript-closure.html
    heroicYang
    heroicYang
    May 30, 2013
    18
    直白点一句话剧透:闭包就是内部函数能访问外部的变量。如果要深究,5楼已答,但是个人觉得这个概念你越是深究反而越糊涂。
    Hongmin
    Hongmin
    May 30, 2013
    19
    突然想到一点,关于C语言函数中的static变量。

    int counter() {
    static unsigned v = 0;
    return v++;
    }
    是不是一个闭包?
    davepkxxx
    davepkxxx
    May 30, 2013
    20
    关于那个考题

    var abc = (func)();

    和

    var abc = (func());

    的结果当然没区别……
    heroicYang
    heroicYang
    May 30, 2013
    21
    关于考题,还有第三种写法:
    var abc = function () {
    return {};
    }();
    tangzx
    tangzx
    May 30, 2013❤️1
    22
    闭包是离散数学中一个入门概念,表示一种作用域在有/无向图上的运算,其输入为图上一个点,输出为一个图上点的集合。

    编译原理中,有些计算机语言设计为:以闭包运算来决定变量的作用域

    于是,讨论这些语言时就难免讨论到闭包,于是闭包便编程一个程序员用语了
    chemzqm
    chemzqm
    May 30, 2013
    23
    实践中能别用就别用闭包,看过太多闭包滥用,没法阅读的代码
    slixurd
    slixurd
    May 31, 2013
    24
    @Hongmin 我觉得这样不行吧= =
    不然java的匿名内部类怎么办?
    congteng
    congteng
    May 31, 2013
    25
    最简单的闭包
    var a = 1;
    function test(){
    return a + 1;
    }

    test();
    RockHammer1947
    RockHammer1947
    OP
    May 31, 2013
    26
    理解了

    @congteng 给出了五楼的例子

    @renyuan1985
    @heroicYang
    @Hongmin
    @davepkxxx
    @heroicYang
    @tangzx
    @chemzqm
    @slixurd

    thank u guys
    AlfredZhao
    AlfredZhao
    May 31, 2013
    27
    @switch 正解...闭包不是拿来装样子的,要真正理解才可以。Object:带有行为的数据,Closure:带有数据的行为...
    RockHammer1947
    RockHammer1947
    OP
    Jun 10, 2013
    28
    @switch

    (function( window , undefined ){

    })( window );

    变成下面这样的时候就形成了闭包

    (function( window , undefined ){
    var abc = 'x';
    var z = function(){
    console.log(abc);
    }
    z();
    })( window );

    “一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套在其中的父函数的参数与变量。通过函数字面量创建的函数对象包含一个连接到外部上下文的连接。这被称为闭包(closure)。它是JavaScript强大表现力的来源。”----蝴蝶书 page 27
    yakczh
    yakczh
    Jun 10, 2013
    29
    闭包就是数据的作用域
    RockHammer1947
    RockHammer1947
    OP
    Jun 10, 2013
    30
    @heroicYang 哈哈,我理解了,如果是匿名函数还有第种写法 function前加操作符 +,-,~,!
    1、
    (function(){

    })()
    2、
    (function(){

    }())
    3、
    ~function(){

    }();
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2220 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 54ms · UTC 05:09 · PVG 13:09 · LAX 21:09 · JFK 00:09
    ♥ Do have faith in what you're doing.