javascript的预编译

    function  fn(a) {
        console.log(a);  //    function a() {}
        var a = 123;
        console.log(a);  // 123
        function a() {
        }
        console.log(a);  // 123
        var b = function () {}
        console.log(b);  //function () {}
        function d() {}
    }
fn(1);

首先来看上面的一道题。

整个执行的顺序,会先创建一个全局对象(GO),首先去找在全局中有无变量的申明,如果有,就先把它的值赋为undefined,然后再去找有无函数申明。这样完成一个预编译的过程。然后在去执行,如中的fn是申明的函数,在预编译阶段已经添加到全局对象中,所以在执行的时候  function fn(a) {..} 会先跳过。然后就执行到 fn(1)的语句。此时要去执行fn的函数,在执行函数的时候,也会先预编译,在函数里的预编译会创建一个AO对象。那么在函数的预编译阶段,会先找到形参和函数里的变量申明,并将值赋为undefined。然后将形参和实参的值统一。之后再找到申明的函数。

就拿上述的例子来说,AO对象的变化过程回事这样的。

//1.找到所有形参和实参的值,并赋为undefined
AO {
   
   a:undefined
   b:undefined

}
//2.将形参和实参的值统一

AO {
  
   a:1
   b:undefined
}
// 3.找到申明的函数

AO {
  
   a:function a (){}
   b:undefined
}

接下来就是一步一步执行函数体内的代码

此时 console.log(a) 在AO对象里a的值为  function a() {},所以输出的为  function () {}.

var a = 123,这句代码,将AO里的a的值改变为123,此时打印a为123.

由于function a() {}在预编译阶段已经完成申明,所以跳过这边。

接下来还是打印a的值,由于a的值为发生改变,所以  打印出来a的值仍是 123.

接下来 var b = function (){},是变量赋值的情形,所以此时AO中的值为 function(){}.

所以打印出b的值为 function(){}.

扫描二维码关注公众号,回复: 2284539 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_36626755/article/details/81111924