函数内的变量, 如果未声明, 且和某个全局变量(内置的或自己定义的)名称相同的话, 实际上是那个全局变量. 话说, 难道每个JavaScript程序员都熟知所有的全局变量? 且熟记自己使用的所有全局变量?再看这个更变态的代码: function a(){
for(i=0;i<20;i++){
}
}
function b(){
for(i=0;i<3;i++){
a();
}
return i;
}
document.writeln(b());
结果输出是什么? 没错, 是21.感觉JavaScript就是个一家亲, 合着变量大家一起用, 不分什么函数内部外部的. 可是还不要求必须声明变量, 我想问, 如果对于大型的程序, 有没有程序员敢不声明就使用变量的.

解决方案 »

  1.   

    你在函数内当然可以访问到外部的全局变量啦  这貌似多数语言都是吧
    如果想在函数内部定义属于自己的变量 就用var来定义  这样他会影藏同名的全局变量
    <script type="text/javascript">
     function a(){
            for(i=0;i<20;i++){
            }
        }
        function b(){
            for(var i=0;i<3;i++){
                a();
            }
            return i;
        }
        document.writeln(b());
    </script>
    类似于这样
      

  2.   

    javascript并不提倡使用全局变量,很多文章都不提倡大面积的使用全局变量,你看过有几个JS程序里面超过了10个全局变量的  至少我没有
      

  3.   

    <script type="text/javascript">
        function a(){
            for(i=0;i<20;i++){
                // 没有 var i
                //这里的i就是全局变量所有人可以访问
            }
        }
        function b(){
            for(i=0;i<3;i++){
                //alert(i);//同理这里的i也是全局变量,返回0且只有一次返回
                a();//这个函数返回是i=20
                //当i=20 经过 i++后 i=21 那么就不符合i<3的条件,直接退出。所以return i=21 这很正常!
            }
            return i;
        }
        document.writeln(b());
        //变量没写var定义就自动变成全局,定义了才是私有变量。人家有规定,是你程序员不遵守!
        //如果上面你改成 for(var i 又试试。要怪自己别怪别人
    </script>
      

  4.   

    呵呵, var声明就是局部变量,没var就是全局变量,3楼说的就是这个意思.我想说的是, 这规则, 太他们的奇葩了.好比, 你们家东西, 必须声明是私有的, 不然大家都可以用, 为什么不反过来, 声明可以大家用的才能是公用, 指定这规则的人肯定后悔了,我看过Javascript那作者说,他只不过花了10天来发明这种语言. 只不过, 这东西流行起来,就不能随便改了.规则很简单, 不过我确实觉得这规则非常欠考虑.
      

  5.   

    等你玩熟了javascript闭包再理性看待这个问题。javascript确实过于灵活,像匹野马,呵呵。
      

  6.   

    全局变量 一定要用 指定的空间前缀访问比如 window.xxxx或者在自己的项目中 构建全局变量的空间
      

  7.   

    所以,你不认同规则的定义,也不认同法律的解释才会这样想。人指的是个体,国家指的是个体的集合、特定环境,这又正如javascript一样,所谓全局指的就是特定浏览器下的环境。
      

  8.   

    思想的奴性不是指机械的遵守,而是一直坚持自己的无知为自由,掌握了真理你学了其他的语言,在学习js的时候发现特性不一样,所以你认为是js这样做不好,多看看几个语言吧。不是每个语言都长得一样的,不然就没必要造轮子了
      

  9.   


    个人认为,javascript过了闭包这一关算是上一个台阶,然后是prototype链,我不相信你搞懂了闭包居然要求局部变量都需要声明?
    <script>
        var Counting = function(){
          var id = 0;
          return function(){
            return ++id;//我就不声明,咱有闭包!
          }
        }
        var C = Counting();
        alert(C())//1
        alert(C())//2
        alert(C())//3
     </script>
      

  10.   


    上面那个例子, 上一层已经声明id, 再声明还能达到目的吗? 闭包如果用类的观点来看, 非常简单, 就是一个隐形的类实例.函数内部不声明, 默认是全局变量, 这个规则, 你再举一个例子, 哪种语言还有? 但在函数内部, 变量不特别指明, 就是局部变量, 是几乎所有语言的规则. 这不能说明问题吗? 你 JavaScript 弄这么个奇怪规则, 还不能说啊.
      

  11.   

    JavaScript的这种设计, 唯一的作用是不用引进一个 global 关键字. 绝大多数语言, 不提供在函数内部声明全局变量的功能, 如果有这种需求, 都是在函数外部提前声明一个变量, 但是在某些时候, 比如只有2个函数互相共享一个变量, 而且这变量没有必要在外面声明, 这样程序看起来更简洁, 那么很多语言, 比如C++就没有办法实现这种要求, 你必须在外部, 或者类的头部声明. 而 JavaScript 能做的这一点, 不过事实上, 不推荐这么做, 这是大多数语言不提供这个功能的原因. 因为全局变量对大工程来说, 是不可忍受的, 各部门还要先统一公用变量的名称, 以免冲突. 如果某个人把全局变量写在函数里, 将更难查找.未声明变量, 作用域超过声明过的函数外部的变量, 在JavaScript, 这个功能几乎就没人用, 可以说是废的. JavaScript完全应该要求必须声明变量.
      

  12.   

    楼主学傻辽…………
      1.你好好想想,JS的全局变量和局部变量有什么分别?一回事,只是声明所在的层级不同。
      2.估计你也并不是总愿意用全局变量,所以就嫌经常要局部定义会比较麻烦,这个可以理解。但在哪里用就在哪里声明,也是一种不错的方式。否则你在上面看到一个A,B,C声明,在下面找了1溜18圈,可能都没用上,就算用上了,两下里离得那么远,有时甚至可能在不同的JS文件里,你那么找,累不累?所以,哪里用就在哪里附近写声明,或者使用闭包的方法是最好的,这在很多时候是衡量JS程序员经验能力的标杆。
      3.退一万步讲,按你说的“需要声明为全局变量时去指定为全局变量好不好?”。要不怎么说你都学傻了呢,你忘了JS是什么???它是解释语言啊,读了就干活的,哪有读到后来发现是有一个全局变量,才通知之前的那些方法有这么一个玩意儿?哪有后悔药可吃?你说它的作者应该吃后悔药,那你是用编译语言的思想来看待的,只能说是你吃错药了。
      简单这么想吧,如果它这一点真是个大错铸就已难改的巨大错误,这玩意也不能混这么久也没改正。它的作者没时间,全球这么多高手都是吃闲饭的吗?逆向思考不等于盲目莽撞的叛逆,要相信和尊重全世界IT大师和IT民工的集体智慧。
      

  13.   


      好好想想我上面说的第1. JS的函数可以作为对象使用,在对象里又可以创建函数方法,也就类似函数里套函数。那么你上级对象里创建的在整个上级对象里使用的变量,对于对象里下面的函数来说,是不是也就是上层对象内的一个全局变量???那按你希望的,难道你得在若干多的下级函数里去声明这些变量为全局变量才可以使用?这又麻不麻烦呢?
      其实JS的全局变量,就是window这个顶级对象的内部局部变量。DOM和JS都是对象层级进行一定量的继承的(比如CSS继承),当然下级对象可以直接使用该成员变量,在其它编译型的OOP里好像也没听说继承父对象的子对象在使用父对象的成员变量和方法时还需要加命名空间去声明为父变量和方法的,也是一样直接用,除非你在子对象里声明覆盖变量和重构函数。
      

  14.   


    说了这么多,我只问你一句, 你有没有写函数内部变量不加var的情况, 你平时写程序, 是不是这么写的.
      

  15.   

    湖南人说自己美女多,四川人就笑了;
    四川人说自己经济好,上海人就笑了;
    上海人说自己民工多,广东人就笑了;
    广东人说自己款爷多,香港人就笑了;
    楼主说自己太了解javascript,CSDN笑了...
      

  16.   

    没什么可说的,楼主,你经常丢掉var我只能说你编程习惯不好。foolbirdflyfirst 已经解释的很清楚了。在c/c++中作用域问题也是一样的,只不过需要专门去声明一下全局变量,不声明会报错。js只是省去了声明的步骤,更加灵活而已。不喜欢完全可以不用,你直接加一个"use strict"就好(也许楼主都没听说过吧)所谓的全局变量,也是不过是声明在顶级作用域上的变量而已,浏览器里是window对象,nodejs里是globle对象
      

  17.   


    其实想问LZ写js程序多吗?怎么会问这个问题呢?在写js里的闭包函数时,就会出现不加var的变量啊。
    其实js里,不加var的变量并不是指全局变量,而是顺着作用域链一路向上寻找,当在函数的作用域内找不到,自然就往外找。例如function foo(){
     var link = document.getElementById('link');
     var i = 0; link.onclick = functioin(){
      i++;
      /*这里的i就没有var声明
        由于在这个闭包函数中找不到i
        js就顺着作用域链往上找
      */
      alert(i);
     }

    如果按照LZ所说的方式(利用global声明全局变量),那么js就不会存在闭包了,你想想是吗?
      

  18.   


    看你说的很认真, 我回复你一下:顺着作用域链往上找, 这几乎是大多数语言都遵循的原则, 关键雷人的地方在于, JavaScript在最终找不到声明这个变量, 而创建它的位置, 一般语言显然应该在变量名第一次出现的那个域, 但是JavaScript把它放到最顶端的域.JavaScript这种方法有个好处, 就是变相强制程序员把局部变量加上var, 不然它会自动往上找并且在最顶端创建它, 谁都不希望这样, 所以会老老实实的加上var, 而JavaScript引擎可以因此减少无谓查找的工作量, 如果某个程序员就是靠变量名来保证程序不会出问题, 那么JavaScript引擎, 将会每遇到一个变量都在各级域里面看看, 前面是不是已经定义过了, 大大降低了效率.所以强制变量声明, 是最好, 最完美的解决办法, "use strict"是后加的特性, 我还真知道.最后, 雷人的关键还是, 把未加var的变量在最顶端创建这一点. 闭包的情况, 是你误解不是我误解了, 闭包当然不能加var, 不然是一个新变量了, 如果加了global也是一个新变量, 不管有没有global关键字, 或者规定默认不加var是局部变量, 都不影响闭包的机制(但是因为查找机制, 会略微降低效率).强制变量声明即解决了潜在的作用域混淆, 也避免了对每一个变量都进行上溯查找, 因为只有未加var的变量需要查找.其实不捞你们费心, 你们说的我都知道. 不过你提醒了我可能出于执行效率(避免向上级查找)的考虑, JavaScript变相要求程序员一定要加上var.其实我真想问问, 这么多JavaScript程序员, 你们在写程序的时候喜欢不加var吗? 反正我觉得想声明一个变量不加var的做法, 隐患非常大.(别搅合闭包必须加和必须不能加的情况, 那就不是习惯问题, 而是对错的问题了)
      

  19.   

    这个完全可以通过声明去避免啊!ruby里的变量都不需要声明。我觉得这是给人提供方便。如果有问题,避讳一下就可以了。
      

  20.   


    个人认为,javascript过了闭包这一关算是上一个台阶,然后是prototype链,我不相信你搞懂了闭包居然要求局部变量都需要声明?
    <script>
        var Counting = function(){
          var id = 0;
          return function(){
            return ++id;//我就不声明,咱有闭包!
          }
        }
        var C = Counting();
        alert(C())//1
        alert(C())//2
        alert(C())//3
     </script>兰州烧饼,看大婶的回帖,学会了闭包,真心感谢了
      

  21.   

    哦,csdn的帖子不能多层引用.刚刚我发的帖子,显示起来很有问题.
    如果确实不提供多层引用,就把之前的引用都删去啊,只留直接回复的.
      

  22.   

    楼主,我想说其实我也一直在纠结这个问题。原来我也一直认为这是个设计缺陷,但看了楼上的帖子,我觉得这个设计还是有一定道理的。js这种设计虽然使开发者到处都要写var来定义局部变量(几乎没有不用var的情况),使开发变得很不方便。但是也因此js得到了闭包这个功能,使变量的继承变得更方便。而后者带来的方便应该是大于前者带来的不方便的。首先我们假设js设计成不声明就是局部变量,global声明全局变量,不存在var这个东西。
    然后在29楼的例子中,函数的子函数中需要拿到的变量i其实是上一级函数中的变量,不是全局的,所以global获得不到。那么这么写就无法实现功能,就不存在这种方便的写法。
    (如果要实现相同的功能,还要再加一个parent或者其他名字的关键字来递归获取上级变量。)所以这样设计是很灵活的。
      

  23.   

    javascript中变量的声明、作用域
    http://3aj.cn/article/581.html