初学 JS,对着书上的例子做抄写员,发现一个奇怪的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
nervouna
V2EX    Javascript

初学 JS,对着书上的例子做抄写员,发现一个奇怪的问题

  •  
  •   nervouna 2013-08-03 02:48:32 +08:00 5858 次点击
    这是一个创建于 4470 天前的主题,其中的信息可能已经有所发展或是发生改变。
    function createFunctions(){
    var newArray = [];

    for (var i=0; i<10; i++){
    newArray[i] = function(){
    return i;
    }
    }

    return newArray;
    }

    这这个函数不是应当返回 [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]吗?为啥现在返回的是:

    [function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}, function (){return i;}]

    随时做好被人发现低级错误的准备 =..=!
    第 1 条附言    2013-08-04 13:18:49 +08:00
    楼主已经发现自己错了=v=
    多谢各位
    22 条回复    1970-01-01 08:00:00 +08:00
    yesmeck
        1
    yesmeck  
       2013-08-03 03:03:46 +08:00   1
    什是返回 [9, 9, 9, 9, 9, 9, 9, 9, 9, 9] ?
    AWSAM
        2
    AWSAM  
       2013-08-03 03:04:59 +08:00 via iPad   2
    没学过js
    不过看代码 你定义了一个函数然后赋值给数组中的元素 返回的当然是函数了啊
    想返回999 应该 调用 而不是 定义 函数吧
    bixuehujin
        3
    bixuehujin  
       2013-08-03 03:06:16 +08:00   1
    for 里面创建的函数在何处调用?


    话说 [9, 9, 9, 9, 9, 9, 9, 9, 9, 9] 的结果怎么出来的呢?
    qiayue
        4
    qiayue  
    PRO
       2013-08-03 03:07:15 +08:00   1
    你再仔细一句一句看看代码,返回没错,你自己理解错了
    bixuehujin
        5
    bixuehujin  
       2013-08-03 03:08:37 +08:00
    如何函数没有写错的话,结果正确无疑。
    nervouna
        6
    nervouna  
    OP
       2013-08-03 03:19:11 +08:00
    是的,我自己理解错了,深夜脑子秀逗了。感谢楼上几位……

    正确的姿势是再调用一下返回数组里的某个项。

    而且返回的数组里的函数,返回的值其实应当是 10

    @yesmeck
    @AWSAM
    @bixuehujin
    @qiayue
    utom
        7
    utom  
       2013-08-03 03:29:32 +08:00   1
    function createFunctions(){
    var newArray = [];
    for (var i=0; i<10; i++){
    newArray[i] = function(){
    return i;
    }();
    }
    return newArray;
    }

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    coolicer
        8
    coolicer  
       2013-08-03 10:59:55 +08:00
    你把一个函数给一个数组,肯定全都是函数。
    coolicer
        9
    coolicer  
       2013-08-03 11:00:21 +08:00   1
    JS讨论可以找我,我也是JS爱好者。
    utom
        10
    utom  
       2013-08-03 22:53:42 +08:00   1
    newArray[i] = function(){ return i; }(); 后面括号立即执行~
    linkgod
        11
    linkgod  
       2013-08-03 23:20:00 +08:00   1
    第一,就算如LZ所愿,也不会反回 [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],应该是返回 [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

    第二,回到js语言上来看,在执行到

    ```
    newArray[i] = function(){
    return i;
    }
    ```

    这个函数并没有立即执行,应该是

    ```
    newArray[i] = (function(){
    return i;
    })();
    ```
    这样才对,就得到[0, 1, 2, 3, 4, 5, 6, , 8, 9]
    PotatoBrother
        12
    PotatoBrother  
       2013-08-04 10:52:10 +08:00 via iPhone   1
    应该是楼主错了,不是程序错了
    cave
        13
    cave  
       2013-08-04 12:12:15 +08:00   1
    为什么不是 [function (){return 0;}, function (){return 1;}, function (){return 2;}, function (){return 3;}, function (){return 4;}, ...]
    linkgod
        14
    linkgod  
       2013-08-04 13:25:09 +08:00
    @cave 因为这里是始终访问的createFunctions作用域里面的i
    cave
        15
    cave  
       2013-08-04 13:43:22 +08:00
    @linkgod 但是createFunctions自己的作用域里面并没有定义i
    linkgod
        16
    linkgod  
       2013-08-04 14:17:18 +08:00
    @cave 有呀!你注意看那个for循环,i就是在那定义的。
    cave
        17
    cave  
       2013-08-04 15:23:17 +08:00
    说错了,是匿名函数里面没定义i
    viger
        18
    viger  
       2013-08-05 16:41:11 +08:00   3
    1, 首先楼主在赋值给数组元素的是一个函数对象,而不是函数的结果。所以你运行后打印出的结果肯定是函数体。
    2,当你再次执行这些数组元素的函数对象时结果肯定是[10,10,10...10],为什么不是[9,9,9...9呢],其实这个要从Javascript这种语言的特性说起。简单的说是其变量作用域的问题。一般强类型语言变量i的作用域只在循环内部可访问。JS不是。你可以在console中执行for(var j =0;j<10;j++);console.log(j);结果显示的是10,而不是undefined.
    3,楼上的朋友说在函数后面加上()即可马上执行函数,建议是(function(){})()这样写比较好;随便楼主可以google下JS闭包。
    ,注意变量申明时一定要var一下。如果没有,JS默认此变量是全局变量。

    @cave 匿名函数虽然没有定义i,但是JS的特性是该作用域内没有的自动从其父作用域中寻找变量。这个无需担心。当然有时候也会造成很多奇怪的错误,好的做法是即使var变量。
    nervouna
        19
    nervouna  
    OP
       2013-08-05 16:55:42 +08:00
    @viger 是的,我就是在看书的时候看到闭包,对着书上一个「错误做法」的例子做实验,发现这个问题的。
    otakustay
        20
    otakustay  
       2013-08-05 18:26:27 +08:00
    为什么所有玩js的都喜欢主动去踩一下这个坑- -
    FrankFang128
        21
    FrankFang128  
       2013-08-05 18:32:53 +08:00
    这不是坑。
    不理解的地方就应该多试试。
    mrhooray
        22
    mrhooray  
       2013-08-06 12:55:18 +08:00
    @viger 貌似大多数语言都有你说的这个js特性。。。感觉应该是js只有global scope和function的local scope,没有一般语言的lexical scope

    https://developer.mozilla.org/en-US/docs/Web/Javascript/Guide/Values,_variables,_and_literals#Variable_scope
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5018 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 03:55 PVG 11:55 LAX 20:55 JFK 23: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