Javascript作用域

用几个经常会碰到的变态笔试题弄懂Javascript作用域吧! 

1.练习 

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

  1.1 以上代码JS是如何解析的呢?

  首先,我们要明白Javascript的解析过程有定义阶段和执行阶段,那么我就用我理解的来做这些练习题

  分析:

    (1) 定义 (var和函数声明)

      var a ;

        function a() {alert(2);}

      在定义阶段就只有这两个,而因为它们的名字相同,所以var a会被忽略,那么就只剩下

      function a() {alert(2);},于是在定义阶段只剩下函数声明

    (2) 执行

      来到执行阶段,OK,那就一步步往下执行好了

      alert(a)    // 定义阶段有function a() {alert(2)},于是会弹出这个函数体

      a = 10;   // 这一步是赋值,上一步相当于 var a = function() {alert(2);},这一步改变了a的值

      alert(a)   // 10

      a();  // 这里会报错,a is not function,因为此时a已经赋值为10,那么10()是什么呢?所以会报错

  1.2 于是乎,以上这道题的答案就是,首先弹出function a() {alert(2);} ,然后再弹出10.

2.练习

 1 alert(a);
 2 var a=10;
 3 
 4 alert(a);
 5 function a(){
 6     alert(20);
 7 }
 8 
 9 alert(a);
10 var a=30;
11 
12 alert(a);
13 
14 function a(){alert(40);}
15 alert(a);

  2.1 上面这道题看上去是不是也会很晕呢?那么JS到底是怎样解析的呢?其实通过上面的分析,很快就会得出答案

  分析:(由于上面已经分析得很详细,那么下面的分析思路就省略了)

    (1) 定义 (var和函数声明)

      var a;

      function a(){alert(20);}

      var a;

      function a(){alert(40);}

      最后剩下function a(){alert(40);} 

    2.执行

      第1条语句  alert(a)  //function a(){alert(40);}

      第2条语句  a = 10   //给a赋值

      第3条语句  alert(a)  //10

      第4条语句是函数声明,是在定义阶段,不是执行阶段

      第5条语句  alert(a)  //10

      第6条语句  a = 30;  //赋值

      第7条语句 alert(a)  //30

      第8条语句同第4条语句都是函数定义

      第9条语句  alert(a)  //30

  2.2于是乎,上面的执行结果为function a(){alert(40);},10,10,30,30

3.练习

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

  3.1分析JS的解析过程

    1.定义

       function a(){alert(2);}

    2.执行

      a();  //2;

      a = function(){alert(1)};  //赋值

      a();  //1

      a() // 1;

      a = function b(){alert(3)} //赋值

      a() //3

    3.2 以上执行结果为2,1,1,3

4 练习

1 var a = 0;
2 function fn(){
3     alert(a);
4     var a = 1;
5     alert(a);
6 }
7 fn();

  4.1分析

    (1) 定义

      var a;

      function fn(){alert(a);var a=1;alert(a);}

    (2) 执行

      fn() //fn()作用域

          (1) 定义

            var a;

          (2) 执行

            alert(a)  //undefined

            a = 1;  //赋值

            alert(a)  //1

  4.2 这里就会有全局作用域和局部作用域的考察,在fn()作用域中,当函数执行完成,变量会销毁.结果为undefined,1

5.练习,如果我们将第四道题稍微改定一下,讲fn()函数里声明的变量a,var去掉那会怎样呢?

1 var a = 0;
2 function fn(){
3     alert(a);
4     a = 1;
5     alert(a);
6 }
7 fn();

  5.1 分析

    (1) 定义

      var a;

      function fn(){alert(a);a=1;alert(a)}

    (2) 执行

      fn() // fn()作用域

          (1) 定义

             在此作用域未定义

          (2) 执行

            alert(a)   //会往上级作用域查找a,于是弹出0

            a = 1 //赋值

            alert(a)  //1

  5.2 结果为0,1

6.练习

1 fn();
2 alert(a);
3 var a = 0;
4 alert(a);
5 function fn(){
6     var a = 1;
7 }

  6.1 分析

    (1) 定义

      var a;

      function fn(){var a=1;}

    (2) 执行

      fn() // 什么也不做

      alert(a)  //undefined

      a = 0;  //赋值

      alert(a)  //0

  6.2 结果弹出undefined,0

7.练习

 1 fn();
 2 var a = 0;
 3 function fn() {
 4    alert(a);
 5    var a = 3;
 6    function c() {
 7        alert(a);
 8     }
 9     return c;
10 }

  7.1 分析

    (1) 定义

      var a;

      function fn(){alert(a);var a=3;function c(){alert(a)};return c;}

    (2) 执行

      fn() //fn()作用域

          (1) 定义

            var a;

            function c(){alert(a);}

          (2) 执行

            alert(a)  //undefined

            a = 3;  //赋值

  7.2执行结果:弹出undefined

8.练习

1 var a = 1;
2 function fn(a){
3     alert(a);
4     a++;
5     alert(a);
6 }
7 fn(a);
8 alert(a);

  8.1 分析

    (1) 定义

      var a;

      function fn(a){alert(a);a++;alert(a)} 

    (2) 执行

      a = 1; //赋值

      fn(a)  //fn()作用域

          (1)  定义

            var a;   //参数

          (2)  执行

            a = 1; //赋值

            alert(a)  // 1

            a++ ;  //2

            alert(a)   //2

      alert(a)   //1

  8.2 结果为弹出1,2,1

9.练习,对练习8的稍作改动,如果这时候fn函数定义的时候没有参数会怎样呢?请看下面的分析

1 var a = 1;
2 function fn(){
3     alert(a);
4     a++;
5     alert(a);
6 }
7 fn(a);
8 alert(a);

  9.1 分析

    (1) 定义

      var a;

      function fn(){alert(a);a++;alert(a);}

    (2) 执行

      a = 1;  //赋值

       fn(a)  //fn()作用域

          (1) 定义

          (2) 执行

            alert(a)   //因为fn()作用域没有定义变量a,所以会向上查找 ,结果找到了a = 1,于是弹出1

            a++  //2

            alert(a)  //2

     alert(a)   //此时的a是多少呢?可以看到fn()里弹出的a是全部作用域,而这里即将弹出的a也是全局作用域,所以应该弹出2,而不是1

  9.2执行结果为:1,2,2

10 总结

  如此通过上述Javascript作用域的详解发现,只要我们清楚在定义阶段有哪些,在执行阶段变量的值,那么对于这样的题目只要仔细分析,就不会太难了吧!!嘿嘿,是不是收获很大呢?

原文地址:https://www.cnblogs.com/tangyuchen/p/5821036.html