有熟悉 js 的大神么?一个 var 命令疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
aliehuhu
V2EX    Python

有熟悉 js 的大神么?一个 var 命令疑问

  •  
  •   aliehuhu 2017-08-27 10:50:36 +08:00 6393 次点击
    这是一个创建于 3041 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <div class="box" id="a1"></div>
    <div class="box" id="a2"></div>
    <script type="text/Javascript">
    var a=[],b=[];
    for(var i=0;i<10;i++){
    a[i] = function(){
    document.getElementById('a1').innerHTML = i;
    };
    b[i] = i;
    }
    a[6]();
    document.getElementById('a2').innerHTML = b[6];
    </script>

    为什么 a[6]() 输出结果是 10,而 b[6]输出结果是 6 ?
    32 条回复    2017-08-28 18:00:30 +08:00
    wwqgtxx
        1
    wwqgtxx  
       2017-08-27 10:55:04 +08:00
    因为闭包
    ClassicOldSong
        2
    ClassicOldSong  
       2017-08-27 10:55:49 +08:00 via Android
    典型的闭包问题
    we2ex
        3
    we2ex  
       2017-08-27 11:26:55 +08:00
    从 ES6 就不建议用 var 了,用 let 吧
    SuperMild
        4
    SuperMild  
       2017-08-27 11:31:49 +08:00
    用 let。
    在 js 节点右侧栏有个优秀的闭包教程 /go/js
    addywu
        5
    addywu  
       2017-08-27 11:31:56 +08:00 via Android
    var 作用域
    klesh
        6
    klesh  
       2017-08-27 11:32:18 +08:00 via Android   1
    a[i] = (function (ii){
    return function (){
    document.get... = ii;
    };
    })(i);
    Parabolazz
        7
    Parabolazz  
       2017-08-27 11:36:04 +08:00
    搜索一下 js 闭包
    crystom
        8
    crystom  
       2017-08-27 11:38:41 +08:00
    相当于 var i 是在外面定义的
    aliehuhu
        9
    aliehuhu  
    OP
       2017-08-27 11:53:06 +08:00
    @klesh 看了你这个明白了
    asdf123101
        10
    asdf123101  
       2017-08-27 11:54:21 +08:00 via Android
    楼上都说完了不知道该说什么。典型闭包的问题,MDN 上 let 词条里面有例子和解释。
    xrr2016
        11
    xrr2016  
       2017-08-27 12:10:10 +08:00
    因为运行 `a[6]()` 的时候变量 i 是 10
    qq12345454
        12
    qq12345454  
       2017-08-27 12:24:51 +08:00
    用 let 或者 const
    deepkolos
        13
    deepkolos  
       2017-08-27 12:59:34 +08:00
    for 循环结束之后 i 的值为 10
    autoxbc
        14
    autoxbc  
       2017-08-27 14:02:29 +08:00 via iPhone   1
    这是求值时机问题,是无形参函数从作用域链检索变量问题

    直接说闭包问题,显然是给出了解决方法,却回避了问题自身
    siteshen
        15
    siteshen  
       2017-08-27 14:24:23 +08:00   1
    我就想歪楼问下为啥发在 python 节点
    magicdawn
        16
    magicdawn  
       2017-08-27 14:37:46 +08:00
    aliehuhu
        17
    aliehuhu  
    OP
       2017-08-27 18:18:22 +08:00
    @siteshen 顶部导航点节点,没找到 js 节点,再看了看 Python 板块,感觉人要多些,就发这里了。
    aliehuhu
        18
    aliehuhu  
    OP
       2017-08-27 18:26:49 +08:00
    @autoxbc 就是不明白为什么 b[i]可以得到“当时 i 的值”,而 a[i]只能得到“调用时候 i 的值”。
    kotokz
        19
    kotokz  
       2017-08-27 20:00:07 +08:00
    这些都是 Javascript 的坑,尽量用 let
    POPOEVER
        20
    POPOEVER  
       2017-08-27 20:14:51 +08:00
    看你的意图你该在 function 里把 i 传进去呗,直接拿全局 i 当然就是 for 结束后的 10 喽
    autoxbc
        21
    autoxbc  
       2017-08-27 23:22:05 +08:00   1
    @aliehuhu #18

    a[i] 被赋值为函数表达式,也就是函数对象。

    函数对象只能记录自己在定义时的作用域链,不能记录在定义时作用域链上的变量的瞬时值。

    函数引用的变量的值,要在函数被调用时再去读取。
    FrankFang128
        22
    FrankFang128  
       2017-08-27 23:57:04 +08:00
    跟闭包有毛关系?
    原因是执行时机。你把 a[6]() 提前执行不就是 6/7/8/9 了吗?
    服了上面一群说闭包的。
    FrankFang128
        23
    FrankFang128  
       2017-08-27 23:57:46 +08:00
    @autoxbc 所以我说 V2 上面大部分自称前端的都很水。
    lhstock
        24
    lhstock  
       2017-08-28 00:00:47 +08:00
    额,楼上的所有人。我想说。作用域你妹啊。
    > document.getElementById('a1').innerHTML = i; //给此元素内容写入 i

    循环完了当然是 10 ;
    还有
    @aliehuhu
    a[6]()输出结果为 10 这个说法不对。输出是 undefined ;写入的是 10
    lhstock
        25
    lhstock  
       2017-08-28 00:01:30 +08:00
    @FrankFang128 握爪
    FrankFang128
        26
    FrankFang128  
       2017-08-28 00:04:04 +08:00   1
    另外,说闭包的人其实说的是「立即执行函数」,这些人把「立即执行函数」称为「闭包」而不自知。
    xman99
        27
    xman99  
       2017-08-28 09:44:21 +08:00
    b(6) 已经是调用函数了, 没问题啊
    iWtbAbh
        28
    iWtbAbh  
       2017-08-28 09:54:45 +08:00
    @aliehuhu 别被误导。
    @lhstock 与其去猜,加上 debugger 在浏览器里跑一遍,就知道了。
    lhstock
        29
    lhstock  
       2017-08-28 12:00:05 +08:00
    @iWtbAbh 你在猜啊。那闭嘴吧
    iWtbAbh
        30
    iWtbAbh  
       2017-08-28 15:08:29 +08:00
    @lhstock 嗨呦,我选择说话就是错了, 毕竟 v2 大佬多。

    虽然被你恶心到了,但我为自己说的话负责。

    "输出是 undefined ;写入的是 10"

    避免误导别人,这是过程,就花了不到一分钟

    ![]( )

    在执行 a[6] () 前 i 已经被赋值了,哪来 undefined ?你能给我看看证据么,万分感谢。

    不然我说猜的有错?
    lhstock
        31
    lhstock  
       2017-08-28 17:17:18 +08:00
    @iWtbAbh
    提问原话为:“为什么 a[6]() 输出结果是 10,而 b[6]输出结果是 6 ?”
    我理解为:console.log(a[6]());console.log(b[6]);

    被赋值的是 a[6];
    而 a[6]=Fun ;

    没有返回值;自然是 undefined ;
    不然换个说法 a[6]是个方法;方法哪有值;
    有错么;
    你要不服你把代码 56 行替换为'''console.log(a[6]() '''好吧;
    基本概念理解有误导致描述有误;
    无脑喷什么
    iWtbAbh
        32
    iWtbAbh  
       2017-08-28 18:00:30 +08:00
    @lhstock 不好意思,是我理解错了。

    a[6]() 没有 return , 默认返回 undefined。

    而我把楼主问的问题加了自己主观的理解, 理解成输出结果的是 i 。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2948 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 12:55 PVG 20:55 LAX 04:55 JFK 07:55
    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