资讯专栏INFORMATION COLUMN

JS预编译

skinner / 1689人阅读

摘要:执行结果执行了函数同名函数后者会覆盖前者函数执行了函数函数执行了函数执行结果执行了声明式函数在预编译期声明函数及被处理了,所以即使调用函数放在声明函数前也能执行。

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代码,所以才有这样的结果。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78330.html

相关文章

  • JavaScript-编译

    摘要:预编译发生在函数执行前也就是说函数执行时,预编译已经结束。五总结理解预编译需要明白变量函数声明和变量赋值。预编译阶段,只进行变量函数声明,不会进行变量的初始化即变量赋值,所有变量的值都是变量赋值是在解释执行阶段才进行的。 一、JS的概念 JavaScript ( JS ) 是一种具有函数优先的轻量级解释型或即时编译型的编程语言。 二、JS语言特点 2.1 单线程 (1)JavaScri...

    Aldous 评论0 收藏0
  • vue-cli配置编译

    摘要:转载文章公司的平台功能越堆越多,打包也越来越费劲,一次十几分钟,运维很不爽,捣鼓了一下预编译,试了一下大概缩短了七八分钟,目前感觉还行,现在把它记下来,给需要的童鞋当做参考,也给自己记录一下。 (转载文章)公司的平台功能越堆越多,打包也越来越费劲,一次十几分钟,运维很不爽,so捣鼓了一下预编译,试了一下大概缩短了七八分钟,目前感觉还行,现在把它记下来,给需要的童鞋当做参考,也给自己记录...

    KnewOne 评论0 收藏0
  • 5分钟读懂JavaScript编译流程

    摘要:大家都知道是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢脚本执行引擎都做了什么呢今天我们就来看看吧。全局域就是一切声明的全局变量,全是的属性等同于函数预编译发生在函数执行前一刻。 大家都知道JavaScript是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧。 1-JavaScr...

    Baoyuan 评论0 收藏0
  • javascript引擎执行的过程的理解--语法分析和编译阶段

    摘要:所以觉得把这个执行的详细过程整理一下,帮助更好的理解。类似的语法报错的如下图所示三预编译阶段代码块通过语法分析阶段之后,语法都正确的下回进入预编译阶段。另开出新文章详细分析,主要介绍执行阶段中的同步任务执行和异步任务执行机制事件循环。 一、概述 js是一种非常灵活的语言,理解js引擎的执行过程对于我们学习js是非常有必要的。看了很多这方便文章,大多数是讲的是事件循环(event loo...

    molyzzx 评论0 收藏0
  • js编译过程

    摘要:所以变量声明提升和函数声明提升会出现一个先后顺序预编译过程结束。 先科普: 1.javaScript是解释型语言,就是编译一行,执行一行.....2.javaScript没有块级及作用域......3.javaScript具有变量和函数声明提升功能.....4.AO对象和GO对象....5.预编译就是解决代码执行顺序问题,与java语言类似(jvm).... 例如: (function...

    FWHeart 评论0 收藏0

发表评论

0条评论

skinner

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<