zoukankan      html  css  js  c++  java
  • js函数和变量的执行顺序【易错】

    js函数和变量的声明与执行顺序

    一、函数执行顺序

    1、正常顺序  

    1     function f(){
    2             alert(2);
    3       }
    4       f();        //alert 2  

      所有浏览器都能测试通过。

    2、倒序调用

    1      f();        //alert 2
    2         function f(){
    3             alert(2);
    4         }

      之前一些浏览器会报undefined,不过,目前的版本大多都可以了

    3、含参函数倒序

    1         f(2);        //alert 2
    2         function f(a){
    3             alert(a);
    4         }    

      目前主流浏览器一样可以正常测试通过

    4、声明式函数和赋值式函数

    1         f();                        // 2
    2         function f() {              // 声明式函数
    3             console.log(2);
    4         }
    5         f1();                       // Uncaught TypeError: f1 is not a function
    6         var f1 = function () {      // 赋值式函数
    7             console.log(2);
    8         }  

    声明式函数与赋值式函数的区别在于:在JS的预编译期,声明式函数将会先被提取出来,然后才按顺序执行js代码。

    二、变量执行顺序

    1、正常顺序

    1         var a  =2;
    2         alert(a);       //alert 2    

    2、倒序使用变量

    1         alert(a);       //alert undefined
    2         var a  =2;

      在变量未定义之前使用,会返回undefined。

    3、局部变量的执行

    *注意:js中全局var声明的为全局变量  函数体内var声明为局部变量(函数外部访问不到)但是,函数体内未用var声明的为全局变量(函数外部可以使用)

    1         function f(){
    2             alert(a);
    3             a = 3;
    4         }
    5         f();       //error: a is not defined

      这里Firefox的控制台中会报错ReferenceError(引用错误):a 未被定义。。。。所以建议函数体内最好用var声明变量,保持局部性 如:

    1         function f(){
    2             alert(a);
    3             var a = 3;
    4         }
    5         f();        //undefined    

      这里alert语句可以弹出,虽然是undefined ,但是没有报错,这是为什么呢?? 

      事实上,JS的解析过程分为两个阶段:预编译期(预处理)执行期

      预编译期 JS会对本代码块中的所有var声明的变量函数进行处理(类似与C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。

      执行期 会按照代码块的顺序逐行执行。。

     *函数内部 再次声明赋值,函数f()内有局部变量a时,会优先使用自己的变量,只不过第一次alert时未赋值

    1         var a = 1;
    2         function f(){
    3             alert(a);   
    4             var a = 3;
    5             alert(a);
    6         }
    7 
    8         f();        //undefined 和 3

      *函数内部 再次全局声明,会修改全局的a

    1         var a = 1;
    2         function f(){
    3             alert(a);
    4             a = 2;
    5             alert(a);
    6         }
    7         f();        //1 和 2

      *函数内全局赋值一次,var声明一次    函数f()内还是会优先使用自己的变量a

            var a = 1;                 //           函数f()内变量a的执行顺序
            function f(){
                alert(a);               
                a = 2;                 //                    #2   
                alert(a);           
                var a = 3;             //等价于 var a ;       #1
                                       //      a = 3 ;       #3
                alert(a);
            }
           
            f();                //undefined 2 和 3
            alert(a);       //1       

      函数f()内 变量a 声明与赋值 的执行顺序如上,应该很明确了!!

    *一个经典的例子复习一下:

     1              var a,b;
     2              (function(){
     3                  alert(a);          //undefined
     4                  alert(b);          //undefined
     5                  var a=b=3;             //等价于 var a = 3 ; b = 3; b是全局的
     6                  alert(a);          //3
     7                  alert(b);          //3
     8              })();
     9              alert(a);              //undefined
    10              alert(b);              //3

    三、总结

      1、JS的解析过程分为两个阶段:预编译期(预处理)执行期

        预编译期 JS会对本代码(两个script块互不影响)中的所有var声明的变量函数进行处理(类似与C语言的编译)

        此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。

        执行期 会按照代码块的顺序筑行执行

      2、把执行方法写在函数定义之前是不太规范的,但这个界限被弱化了。如今在一个作用范围之内,都可以被正常调用。

      所以,建议和优化如下:

        1.函数体内变量最好var声明为局部,保持安全性和局部性。

        2.所有变量的声明最好一次性写在作用域的顶端,函数不必需如此,如:

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

        3.函数的执行方法 最好在 函数的定义 之后

      

      

      作者:没错high少是我                                                                                                                                                                                     

      出处:http://www.cnblogs.com/highshao/                                                                                                         
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    [BZOJ4444][SCOI2015]国旗计划(倍增)
    [BZOJ4423][AMPPZ2013]Bytehattan(对偶图+并查集)
    [BZOJ4416][SHOI2013]阶乘字符串(子集DP)
    [BZOJ3203][SDOI2013]保护出题人(凸包+三分)
    [BZOJ4026]dC Loves Number Theory(线段树)
    51nod部分容斥题解
    [CodeVS4438]YJQ Runs Upstairs
    [HDU4906]Our happy ending
    牛客网NOIP赛前集训营-提高组(第四场)游记
    [BJWC2011]元素
  • 原文地址:https://www.cnblogs.com/highshao/p/5442460.html
Copyright © 2011-2022 走看看