js基础二(全局与局部作用域解析,作用域链)

一:浏览器读取页面到显示页面做的两件事

1:js预解析

打开浏览器以后,js会去找一些东西,比如:var  function  。。。 也就是变量和函数

    1)var  a= 1;这时,js 会解析var a=未定义

            所有的变量,在正式运行代码之前,都提前赋了一个值:未定义。

    2)function fun1(){alert(111)}

            所有的函数,在正式运行代码之前,都是整个函数代码块。

2:逐行解析代码

表达式:+ - * % ++ -- Number

alert(a)

var a = 1;

alert(a)

这时候,首先会显示undefiend ,是因为代码逐行解析,到alert的时候,查询变量a ,有定义,所以给赋了个初始值,然后再继续往下读。会弹出1,那是因为表达式可以修改预解析的值,把a赋值了1。

二:一个例子解释浏览器预解析和逐行执行代码过程

 alert(a)

  var a=1;

  alert(a)

  function a() {  alert(2)  }

  alert(a)

  var a = 3;

  alert(a)

  function a(){  alert(4)   }

  alert(a)

js预解析的工作过程

1:预解析,找一些东西,比如:var function  。。。

首先找到,var a=1;  变量会预解析为 a = undefiend ;

接着找到,function a() {  alert(2)  },这个函数a和变量a重名,这种情况会只留一个,会把函数留

                下。 所以解析为 a = function a() {  alert(2)  };

再往下找到,var a = 3;变量会预解析为 a = undefiend ;当变量a和上面的方法a进行pk,方法a就会

                  被踢出,所以解析为 a = function a() {  alert(2)  };

最后找到, function a(){  alert(4)   };当两个函数一起的时候,会遵循上下优先级的原则,所以把a 

                   = function a() {  alert(2)  };踢出,所以解析为   a = function a(){  alert(4)   };

最后到浏览器仓库里面只剩下 a = function a(){  alert(4)   }


js逐行执行代码过程的工作过程

1:js每次读取都会去找仓库里面的东西。上面js预解析到最后,仓库里面a被赋值为 a = function a(){  alert(4)   };所以,

第一次执行alert(a) 会弹出来函数 function a(){  alert(4)   };

2:接着往下走var a=1;把a赋值为1。通过表达式 " = "可以修改预解析a的值,所以,

第二次执行alert(a) 会弹出来函数 1;

3:接着往下走 function a() {  alert(2)  };只是单纯的声明了一个函数,没有进行赋值,alert(a) 调用的是一个变量,而不是函数,此时仓库里var a = 1;所以,

第三次执行alert(a) 会弹出来函数 1;

4:接着往下走var a = 3;把a赋值为3。通过表达式 " = "可以修改预解析a的值,所以,

第四次执行alert(a) 会弹出来函数 3;

5:接着往下走 function a() {  alert(4)  };也只是单纯的声明了一个函数,没有进行赋值,alert(a) 调用的是一个变量,而不是函数,所以什么也没有发生,所以,

第五次什么也不弹出,继续往下执行;

6:接着往下走alert(a) ,上面第四次执行的时候给a赋值了3,也就是var a= 3,第五次是个函数,没有执行,多以,

第六次执行alert(a) 会弹出来函数 3;

三 带有局部域浏览器预解析和逐行执行代码过程

var a= 1;

function funa() {   alert(a)     var a =2;  }

funa();

alert(a);

js预解析的工作过程

1 :找到变量  var a= 。。。;

2:找到函数  function funa() {   alert(a)     var a =2;  }

js逐行执行代码过程的工作过程

 var a=1;把a赋值为1。a为全局变量  —>  

接着往下走是一个函数 ,不解析   —>  

接着往下走是funa(),遇到了函数调用,实际上就是让函数里面的东西开始执行。这个时候函数是一个局部的域,所以这时候又会发生域解析  var a =。。。; 然后逐行执行代码   —> 

接着执行funa() 里面的alert(a) 此时的a是局部变量a,而不是外面的全局变量a,所以弹出undefiend  —> 

接着执行  var a =2; 给局部变量赋值为2,跳出函数    —> 

最后执行 una()函数下面的 alert(a); 这个时候的a是全局的变量,而第一行var a=1 ,所以弹出 1;

四 带有作用域链的浏览器预解析和逐行执行代码过程

var a= 1;

 function funa()  {   alert(a)   a =2;  }

 funa();

 alert(a);

js预解析的工作过程

1 :找到变量  var a= 。。。;

2:找到函数  function funa() {   alert(a)    a =2;  }

js逐行执行代码过程的工作过程

 var a=1;把a赋值为1。a为全局变量  —>  

接着往下走是一个函数 ,不解析   —>  

接着往下走是funa(),遇到了函数调用,实际上就是让函数里面的东西开始执行。这个时候函数是一个局部的域,所以这时候又会发生域解析 ,然而里面又没有变量也没有函数; 这个时候,js会逐行执行代码   —>

接着执行funa() 里面的alert(a),而这个函数里面没有变量a, 此时js会跳出该作用域,去父级作用域找,var a=1;把a赋值为1。所以弹出1—> 

接着执行  a =2; 这时候a是全局变量,给全局变量赋值为2,跳出函数    —> 

最后执行 funa()函数下面的 alert(a); 这个时候的a是全局的变量,而funa()函数里面a=2了,所以弹出2;

五:带有参数的浏览器预解析和逐行执行代码过程

1:var a= 1;

    function funa(a)  //这里的a => var a=...  然而funa()没有传参 ,所以alert 是 undefiend 

     { 

        alert(a)  //undefiend (当a有参数传进来的是 函数里面的a是局部变量,虽然值为1,但不是全局 

         变量)

     a =2;}         

     funa();

      alert(a);     // 1


2:var a= 1;

    function funa(a) //这里的a => var a=...  然而funa()有传参var a= 1;,所以alert 是 1

    {alert(a)  // 1 (当a有参数传进来的是 函数里面的a是局部变量,虽然值为1,但不是全局变量)

     a =2; } //这时候给a赋值跟全局变量没有关系

     funa(a);

     alert(a); //1

你可能感兴趣的:(js基础二(全局与局部作用域解析,作用域链))