[探讨]各位大佬,你们认为这段代码有形成闭包吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gooqiao
V2EX    编程

[探讨]各位大佬,你们认为这段代码有形成闭包吗?

  •  
  •   gooqiao 2018-09-05 22:45:46 +08:00 via Android 3429 次点击
    这是一个创建于 2648 天前的主题,其中的信息可能已经有所发展或是发生改变。
    function showHelp(help) {
    document.getElementById('help').innerHTML = help;
    }

    function setupHelp() {
    var helpText = [
    {'id': 'email', 'help': 'Your e-mail address'},
    {'id': 'name', 'help': 'Your full name'},
    {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

    for (var i = 0; i < helpText.length; i++) {
    (function() {
    var item = helpText[i];
    document.getElementById(item.id).Onfocus= function() {
    showHelp(item.help);
    }
    })(); // 马上把当前循环项的 item 与事件回调相关联起来
    }
    }

    setupHelp();


    重点在自执行函数上,这个自执行函数有形成闭包吗?
    先说说我的观点,我不认为这有形成闭包,而只是创建了一个新的函数作用域而已。
    为什么我会这么认为,我先说说我对闭包的定义:闭包必须是越过原执行环境访问到了正常情况下不能访问的对象。很明显上述代码中并没有越过原执行环境,所以不形成闭包。

    贴发出来主要是想大家一起讨论下,大家互相交流学习。欢迎大家积极表达自己的意见。
    6 条回复    2018-09-06 16:23:35 +08:00
    Lax
        1
    Lax  
       2018-09-06 01:25:18 +08:00
    那个匿名函数访问到了创建它时的环境变量 helpText。
    只要具备这种访问局部变量的能力就是个闭包。不能因为是原地执行就排除在外了,把这个函数 return 到外部调用方去执行和原地执行没有任何差别。
    Shy07
        2
    Shy07  
       2018-09-06 08:50:49 +08:00 via iPhone
    个人理解:closure 就是封闭的代码块,closure 内部可以访问所在 binding 环境,而 closure 内部环境对外是不可访问的,同时 closure 可以作为参数传递。

    至于 closure 内部可以访问到正常情况访问不到的对象不过是 closure 的一个特性和使用方法而已。你见到一只会飞的鸭子,你不能在它不飞时,就说它不是鸭子了。
    Shy07
        3
    Shy07  
       2018-09-06 08:53:42 +08:00 via iPhone
    @Shy07 立即执行函数的匿名函数部分是闭包
    robinlovemaggie
        4
    robinlovemaggie  
       2018-09-06 12:57:32 +08:00 via Android
    开包我会,闭包是真 TMD 蛋疼
    gooqiao
        5
    gooqiao  
    OP
       2018-09-06 14:35:42 +08:00 via Android
    @Shy07
    如果是这样的话,那是不是就可以认为,只要在函数内部定义的函数用到了外部函数的对象都可以被看错是闭包。
    但是这个内部函数所在的执行环境本就拥有对外部函数定义的对象的访问权限,并没有什么特殊的地方。
    这也是我之所以认为上面代码不形成闭包的原因。
    不知大佬你怎么看?
    Shy07
        6
    Shy07  
       2018-09-06 16:23:35 +08:00
    @gooqiao

    例子中的代码和下面的代码应该是等效的,看到 bind 就可以视作使用了闭包,我是这么认为的

    ```Javascript
    function showHelp(help) {
    document.getElementById('help').innerHTML = help;
    }

    function setupHelp() {
    var helpText = [{
    'id': 'email',
    'help': 'Your e-mail address'
    },
    {
    'id': 'name',
    'help': 'Your full name'
    },
    {
    'id': 'age',
    'help': 'Your age (you must be over 16)'
    }
    ];

    for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).Onfocus= showHelp.bind('item', item.help);
    }
    }
    ```



    另外,**我不是大佬**
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2664 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 05:56 PVG 13:56 LAX 21:56 JFK 00:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86