首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

深入懂得JavaScript的变量作用域

2012-07-02 
深入理解JavaScript的变量作用域1、JavaScript的作用域链2、函数体内部,局部变量的优先级比同名的全局变量高

深入理解JavaScript的变量作用域

  • 1、JavaScript的作用域链
  • 2、函数体内部,局部变量的优先级比同名的全局变量高。
  • 3、JavaScript没有块级作用域。
  • 4、函数中声明的变量在整个函数中都有定义。
  • 5、未使用var关键字定义的变量都是全局变量。
  • 6、全局变量都是window对象的属性

    在学习JavaScript的变量作用域之前,我们应当明确几点:

    • JavaScript的变量作用域是基于其特有的作用域链的。
    • JavaScript没有块级作用域。
    • 函数中声明的变量在整个函数中都有定义。

      1、JavaScript的作用域链

      首先看下下面这段代码:

      view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????var?rain?=?1;??
      3. ????function?rainman(){??
      4. ????????var?man?=?2;??
      5. ????????function?inner(){??
      6. ????????????var?innerVar?=?4;??
      7. ????????????alert(rain);??
      8. ????????}??
      9. ????????inner();????//调用inner函数??
      10. ????}??
      11. ????rainman();????//调用rainman函数??
      12. </script>??

      观察alert(rain);这句代码。JavaScript首先在inner函数中查找是否定义了变量rain,如果定义了则使用inner函数中的rain变量;如果inner函数中没有定义rain变量,JavaScript则会继续在rainman函数中查找是否定义了rain变量,在这段代码中rainman函数体内没有定义rain变量,则JavaScript引擎会继续向上(全局对象)查找是否定义了rain;在全局对象中我们定义了rain = 1,因此最终结果会弹出'1'。

      作用域链:JavaScript需要查询一个变量x时,首先会查找作用域链的第一个对象,如果以第一个对象没有定义x变量,JavaScript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。

      上面的代码涉及到了三个作用域链对象,依次是:inner、rainman、window。

      2、函数体内部,局部变量的优先级比同名的全局变量高。view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????var?rain?=?1;????//定义全局变量?rain??
      3. ????function?check(){??
      4. ????????var?rain?=?100;????//定义局部变量rain??
      5. ????????alert(?rain?);???????//这里会弹出?100??
      6. ????}??
      7. ????check();??
      8. ????alert(?rain?);????//这里会弹出1??
      9. </script>??

      3、JavaScript没有块级作用域。

      这一点也是JavaScript相比其它语言较灵活的部分。

      仔细观察下面的代码,你会发现变量i、j、k作用域是相同的,他们在整个rain函数体内都是全局的。

      view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????function?rainman(){??
      3. ????????//?rainman函数体内存在三个局部变量?i?j?k??
      4. ????????var?i?=?0;??
      5. ????????if?(?1?)?{??
      6. ????????????var?j?=?0;??
      7. ????????????for(var?k?=?0;?k?<?3;?k++)?{??
      8. ????????????????alert(?k?);????//分别弹出?0?1?2??
      9. ????????????}??
      10. ????????????alert(?k?);????????//弹出3??
      11. ????????}??
      12. ????????alert(?j?);????????????//弹出0??
      13. ????}??
      14. </script>??

      4、函数中声明的变量在整个函数中都有定义。

      首先观察这段代码:

      view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????function?rain(){??
      3. ????????var?x?=?1;??
      4. ????????function?man(){??
      5. ????????????x?=?100;??
      6. ????????}??
      7. ????????man();????????//调用man??
      8. ????????alert(?x?);????//这里会弹出?100??
      9. ????}??
      10. ????rain();????//调用rain??
      11. </script>??

      上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值。由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。

      view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????var?x?=?1;??
      3. ????function?rain(){??
      4. ????????alert(?x?);????????//弹出?'undefined',而不是1??
      5. ????????var?x?=?'rain-man';??
      6. ????????alert(?x?);????????//弹出?'rain-man'??
      7. ????}??
      8. ????rain();??
      9. </script>??

      是由于在函数rain内局部变量x在整个函数体内都有定义( var x= 'rain-man',进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出'undefined'是因为,第一个执行alert(x)时,局部变量x仍未被初始化。

      所以上面的rain函数等同于下面的函数:

      view plaincopy to clipboardprint?
      1. function?rain(){??
      2. ????var?x;??
      3. ????alert(?x?);??
      4. ????x?=?'rain-man';??
      5. ????alert(?x?);??
      6. }??

      5、未使用var关键字定义的变量都是全局变量。view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????function?rain(){??
      3. ????????x?=?100;????//声明了全局变量x并进行赋值??
      4. ????}??
      5. ????rain();??
      6. ????alert(?x?);????//会弹出100??
      7. </script>??

      这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。

      6、全局变量都是window对象的属性view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????var?x?=?100?;??
      3. ????alert(?window.x?);//弹出100??
      4. ????alert(x);??
      5. </script>??

      等同于下面的代码

      view plaincopy to clipboardprint?
      1. <script?type="text/javascript">??
      2. ????window.x?=?100;??
      3. ????alert(?window.x?);??
      4. ????alert(x)??
      5. </script> ?

热点排行