zoukankan      html  css  js  c++  java
  • 深入理解JS中的变量及变量作用域

    JS的变量有两种,“全局变量”和“局部变量”。

    “全局变量”声明在函数外部,可供所有函数使用,(全局变量属于window)而“局部变量”声明在函数体内部,只能在定义该变量的函数体内使用。

    1.全局变量:(1)直接在函数外部声明的变量   var a=3

                         (2)在任何位置上,声明变量时没有var关键字,而是直接赋值的变量均为全局变量     s=3

    2.局部变量:(1)在函数内部声明的变量 

                         (2)形参,参数变量天生就是局部变量

    1 <script type="text/javascript">
    2   function main() {  
    3     n = 10;//这里的n为全局变量,可以被外部直接使用
    4   }
    5   main();
    6   alert(n);
    7 </script>

    JS的作用有两种,“全局作用域”和“函数作用域”。

    1.全局作用域:可以在程序的任何位置被访问

    2.函数作用域:  仅能在函数调用时,内部被访问

    注意:在函数体内,局部变量的优先级高于全局变量。

    网上有一个很具有代表性的例子,在函数体外部和内部都申明了相同名字的变量,变量的作用域问题,例子如下:

     1 <script type="text/javascript">
     2   var n = 1;
     3   function test() {
     4     alert(n);  //这里的n并不是全局变量,原因是函数体第四行声明了一个重名的局部变量n, 
     5                  //如果把第四行n的声明注释掉,那么这里的显示1,为全局变量。
     6                 //所以得出结论:全局变量a被局部变量a覆盖了。
     7               //说明了JS函数在test()在执行前,函数体内的变量a都指向了局部变量.
     8             //但本行输出的a在执行过程中还没有被赋值,所以显示undefined。
     9     n = 2;
    10     alert(n);
    11     var n; //本行声明局部变量a
    12     alert(n);
    13   }
    14     test();
    15     alert(n);
    16 </script>

    上面代码的结果为:undefined 2 2 1; 原因就是函数体外部和内部都申明了相同名字的变量时,局部变量覆盖了全局变量。

    外部怎么读取函数体内部的局部变量呢?

    一般来说,只有函数体内部可以直接得到外部的全局变量,但是外部要得到函数体内部的局部变量是不行的。但是,通过在函数体内部再定义一个函数返回局部变量,再从外部调用函数就能实现了。

     1 <script type="text/javascript">
     2   function f1() {    
     3     var n = 10;    
     4     function f2() {//在f1()内部再定义f2(),通过f2()访问f1()中的局部变量      
     5       alert(n);    
     6     }    
     7     return f2;//返回f1()局部变量n
     8   }  
     9   var result = f1(); //在外部调用f1()函数,就能获取局部变量n的值
    10   result(); // 10,即为n的值
    11 </script>

    函数中变量的声明提升

    在程序执行前或函数调用前,将var声明的变量和function声明的函数提升当前作用域的顶部集中创建。

    请看下面的例子:

    1 var v = "hello";
    2 (function(){
    3   console.log(v);
    4   var v = "world";
    5 })();    结果为undefined
    1 var v = "hello";
    2 if(true){
    3   console.log(v);
    4   var v = "world";
    5 }     结果为hello

    上面的代码说明了3个问题:1,function作用域里的变量v遮盖了全局作用域变量v

                 2,在function作用域内,变量v的声明被提升了

                                                3,javascript是没有块级作用域的函数是JavaScript中唯一拥有自身作用域的结构

    上面的代码相当于:

    1 var v = "hello";
    2 (function(){
    3   var v; //declaration hoisting
    4   console.log(v);
    5   v = "world";
    6 })();

    总结:当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明。

    1 (function(){
    2   var a = "1";
    3   var f = function(){};
    4   var b = "2";
    5   var c = "3";
    6 })();

    变量a,f,b,c的声明会被提升到函数作用域的最前面,如下

    1 (function(){
    2   var a,f,b,c;
    3   a = "1";
    4   f = function(){};
    5   b = "2";
    6   c = "3";
    7 })();

    请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:

    (function(){
      //var f1,function f2(){}; //声明提升,被隐式提升的声明
     
      f1(); //ReferenceError: f1 is not defined
      f2();
     
      var f1 = function(){};
      function f2(){}
    })();

    上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。

     

  • 相关阅读:
    超级小白使用pip安装第三方库的正确姿势
    selenium+python自动化测试--解决无法启动IE浏览器及报错问题
    microsoft edge浏览器安装驱动
    超详细MySQL安装及基本使用教程
    Navicat15最新版本破解 亲测可用!!!
    Ubuntu 16.04安装JMeter测试工具
    JMeter_Ubuntu上安装jmeter
    韩国vps推荐-kdatacenter
    全栈之js入门篇
    Web前端之CSS_day5
  • 原文地址:https://www.cnblogs.com/jiayuexuan/p/9263372.html
Copyright © 2011-2022 走看看