JS预编译

if ("a" in window) {
    var a = 1;
}
alert(a);

先来看这个题会alert出什么呢?答案很显然会是:1

不过这道问题放在之前考我的话,那我一定会答错,厥后查找了一番材料,相识到两个新名词:预编译变量提拔,为了今后不会遗忘,照样留个笔记吧。

起首来相识一下什么是预编译:对var关键字(值先设为undefined,实行时才给现实值)和函数定义式举行提早声明,再接着递次实行代码,函数定义式在预编译时代就被剖析,实行时代依然用这个值,而无论是声明的变量照样声明式函数,在实行的时刻,能够掩盖预编译时代的值。

下面我们来解释一下上面的问题为何是1呢,起首上面的代码等价于下面的代码:

var a;
if("a" in window){
    a = 1;
}

由于js没有块级作用域,所以if内里的也是全局的,所以在预编译过程当中内里的变量a会被提出来并被赋值为undefined,然后在实行if语句时刻此时a已存在于window中了,只不过值临时是undefined,因而就会去实行if内里的代码,所以效果为1;

再来一题:

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

等价于:
var a;
a = function(x){}
a = 1;
alert(a);

预编译阶段寻觅代码中的var(现实将var a=1拆分为var a;a=1两部份,第一部份置顶,第二部份挂在语法树上)以及function两个关键字并置顶,在此将a以及a()离别置顶,以后在实行阶段再对a从语法树举行赋值,末了a为1。

理解了上面的代码,下面再看一个相似的问题:

function a(x) {
    return x ;
}
var a;
alert(a);

等价于:
var a;
function a(x){
    return x;
}
alert(a);

这个问题跟上一个有点相似,然则却又差别,缘由就是在这里a并没有被赋值,而只是声明一个变量;在预编译阶段会将这类情势提早置顶,然后将function也置顶,然则function在a以后,因而预编译后两者递次完整倒过来了,所以末了实行效果是function a(x){return x;}。

假如显式的给a赋值一个a=undefined;那末效果就是undefined。由于此时牵扯到赋值了 赋值的话 就在实行阶段去实行。

     Fn();  //实行效果:"实行了函数2",同名函数后者会掩盖前者
     function Fn(){ //函数1
        alert("实行了函数1");
     }
 
     function Fn(){  //函数2
        alert("实行了函数2");
     }
      Fn();  //实行效果:"实行了声明式函数",在预编译期声明函数及被处理了,所以纵然Fn()挪用函数放在声明函数前也能实行。
      function Fn(){ //声明式函数
         alert("实行了声明式函数");
      }
 
      var Fn = function(){  //赋值式函数
         alert("实行了赋值式函数");
      }

经由过程对照上面两段代码,我们不难发明,声明式函数与赋值式函数的区分在于:在JS的预编译期,声明式函数将会先被提取出来,然后才按递次实行js代码,所以才有如许的效果。

    原文作者:shane_xu
    原文地址: https://segmentfault.com/a/1190000004163722
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞