关于变量作用域的一点整理

案例一:

1 var x=100;
2 alert(x);
3 //等同于
4 window.x=100;
5 window.alert(x);

理解:定义的全局变量都是window对象的属性,而一些像alert()这样的默认方法为window对象下的方法。

案例二:

1 alert(x);//弹出undefined
2 var x="yewenxiang";
3 
4 function test(){
5    alert(x);
6    var x="yewenxiang";        
7 }
8 test();//弹出undefined

等价于:

 1 var x;
 2 alert(x);//弹出undefined
 3 x="yewenxiang";
 4 
 5 function test(){
 6   var x;
 7   alert(x);
 8   x="yewenxiang";    
 9 }
10 test()//弹出undefined

理解:Javascript引擎会先扫描整个函数,把所有变量的声明提升到函数体顶部,在函数外面也是会先把全局变量的申明提升到顶部,这个叫变量的提升。

案例三:

1 alert(typeof test); 2 var test=function (){}; 3 //弹出undefined; 4 //等价于 5 var test 6 alert(typeof test); 7 var test=function (){};

alert(typeof test);
 function test(){};
//弹出function;
等价于
function test(){};
alert(typeof test);

理解:函数也会像变量一样被提升,不同的是对于函数声明和定义同时提到前面,而变量只是把声明提到了前面,定义没有提前。

案例四:

 1 var x="yewenxiang";
 2      function test(){
 3          var y="xiangwang";
 4          function test2(){
 5              var z="tiandongxue";
 6              function test3(){
 7                  alert(x);
 8              }
 9              test3();
10          }
11          test2();
12 }
13 test();//弹出yewenxiang;

 理解:函数首先在test3()中查找是否定义了变量x,没有,去上一层test2中查找,没有,再去test1中去找,继续没有,跑函数外面找去了,OK终于找到了var x="yewenxiang",函数内查找变量属于就近原则.

 1 var x="yewenxiang";
 2      function test(){
 3          var y="xiangwang";
 4          var x;
 5          function test2(){
 6              var z="tiandongxue";
 7              function test3(){
 8                  alert(x);
 9              }
10              test3();
11          }
12          test2();
13 }
14 test();//弹出undefined

理解:Javascript也喜欢偷懒,我既然可以在内部找到var x,何必跑出去找var x="yewenxiang".符合函数内局部变量的优先级比全局变量高。

案例五:

function test(){
        var x="yewenxiang";
    }
    test();
    alert(x);//x is not defined 
//因为在函数内部定义var为局部变量,只能在函数内部使用。

function test(){
        x="yewenxiang";
    }
    test();
    alert(x);
//弹出yewenxiang ,不加var,相当于定义了一个全局变量,没调用函数时报错x is not defined,
//调用函数后弹出yewenxiang(注意严格模式下调用函数也会报错x is not defined)。

function test(){
        x="yewenxiang";
    }
    alert(x);
    test();
//报错x is not defined 个人理解只要弹出前没调用函数都报错。

var x="xiangwang"
    function test(){
        x="yewenxiang";
    }
    test();
    alert(x);
//弹出yewenxiang 函数内部的全局变量覆盖了外面定义的var x="xiangwang",
//这种情况下严格模式也没报错,因为函数外面定义了全局变量x。

案例六:

function test(){
         var i=1;
         if(i){
             var j=0;
             for(var k=0;k<3;k++){
                 alert(k);//0,1,2
             }
             alert(k);//3
         }
         alert(j);//j
     }
     test();
//i j k 作用域是相同的,在函数test内是全局的,都可被访问。
function test(){
         let i=1;
         if(i){
             let j=0;
             for(lef k=0;k<3;k++){
                 alert(k);
                 alert(i);
             }
             alert(k);
         }
         alert(j);
     }
     test();//按顺序弹出0-1-1-1-2-1-报错k is not defined-报错j is not defined

理解:let为ES6新增的,解决ES5之前没有块级作用域的问题,这两段段代码说明:函数中的for if while等中定义的var变量,在函数中属于全局变量,都可以被访问。而定义为let,只能在内层去往外层访问定义的let变量,外层访问不了内层定义的let变量.

碰到的坑1:

 1 function test(){
 2         name="yewenxiang";
 3     }
 4     alert(name);
 5 //弹出一个空的对话框。
 6 ------------------------------
 7 function test(){
 8         name="yewenxiang";
 9     }
10     test();
11     alert(name);//弹出yewenxiang 
12 //然后删除test() 刷新页面还是弹出yewenxiang ,然后关闭页面重新加载测试页面弹出空的对话框

执行的结果跟我预料的不一样,我认为的是第一段代码应该报错name为未定义,第二段删除test()后也应该会报错,但是修改代码后刷新页面还是弹出yewenxiang,然后关闭页面重新加载测试页面弹出空的对话框这种诡异的事情,最后发现问题所在:因为name属于Javascript 内置的对象、属性和方法的名称,应该避免使用保留字,换成x后正常。

目前未解决坑2:

1 function test(){
2          alert(x);
3           x="yewenxiang";
4      }
5      test();
6 //报错x is not defined, 如果加var 则变量会提升弹出undefined,不加var 变量为什么没有提升而是直接报错。

以上是我对于变量作用域的一些理解和总结,包括未解决的问题,理解中有错误还希望能指出。

原文地址:https://www.cnblogs.com/yewenxiang/p/6002077.html