js执行顺序

一,js引擎

js引擎就是为读懂javascript代码,准确的给出代码运行结果的程序,这里不过多的研究引擎内部机制,只是探索js运行流程以及和浏览器关系。js引擎是浏览器的组成部分,浏览器引擎负责解析页面、渲染页面、Cookie管理、历史记录等等。JavaScript引擎通常是浏览器自行开发的,好比:IE9的Chakra、Firefox的 TraceMonkey、Chrome的V8等等。javascript

单线程引擎

js引擎是单线程执行的,也就是说在同一时间只有一个线程在执行,而js中事件、计时器、异步回调都是浏览器帮助的,如onclick事件,js单线程加载时注册事件,浏览器会帮助咱们监听这个事件,好比o.onclick=function(){}(o为DOM对象等),当点击发生时:浏览器事件触发线程会为咱们把指定的事件处理程序添加到js引擎当中,js进程时间线空闲时,这段代码执行。java

js单线程执行,因此ajax、事件、settimeout、setinterval是由浏览器新开一个线程请求,当请求的状态变动时,若是先前已设置回调,这异步线程就产生状态变动事件放到JavaScript引擎的处理队列中等待处理。ajax

以下,浏览器引擎和js引擎:浏览器

以下,js进程时间线异步

 

二,js执行顺序

JavaScript是一种描述型脚本语言,不一样于java等编译性语言,它不须要编译成中间语言,而是由浏览器进行动态地解析与执行,执行流程:函数

step 1. 读入第一个代码段spa

step 2. 作语法分析,有错则报语法错误(好比括号不匹配等),并跳转到step5。线程

step 3. 对var变量和function定义作“预解析”(永远不会报错的,由于只解析正确的声明)。code

step 4. 执行代码段,有错则报错(好比变量未定义)。对象

step 5. 若是还有下一个代码段,则读入下一个代码段,重复step2。

step6. 结束。

概念解释

一、代码段

JavaScript中的代码块是指由<script>标签分割的代码段。例如:

<script type="text/javascript"> alert("代码段一"); </script>
<script type="text/javascript"> alert("代码段二"); </script>

JS是按照代码块来进行编译和执行的,代码块间相互独立,但变量和方法共享。

<script type="text/javascript">
    alert(str);//undefined alert("代码段一");
    var test = "1";
</script>
<script type="text/javascript">
    alert("代码段二");
    alert(test); //输出代码段一中变量值:1 
</script>

二、声明式函数与赋值式函数

JS中的函数定义分为两种:声明式函数与赋值式函数。

<script type="text/javascript">
    function Fn(){ //声明式函数 }
    var Fn = function{ //赋值式函数 }
</script>

声明式函数与赋值式函数的区别在于:在JS的预编译期,声明式函数将会先被提取出来,而后才按顺序执行js代码。

三、预编译期与执行期

事实上,JS的解析过程分为两个阶段:预编译期(预解析)与执行期。

经过var关键字定义的变量进行预解析的时候:都是声明declare,无论它有没有赋值,都会赋值undefined

//代码块一
<script type="text/javascript">
    alert(str);//浏览器报错,但并无弹出信息窗 
</script>
//代码块二
<script type="text/javascript">
    alert(str); //undefined
    var str = "aaa";
</script> 
//js在预处理期对变量进行了声明处理,可是并无进行初始化与赋值,因此致使代码块二中的变量是unfiened的,而代码一中的变量是彻底不存在的,因此浏览器报错。

function进行预解析的时候,不只是声明并且还定义(define)了,可是它存储的数据的那个空间里面存储的是代码是字符串,没有任何意义,注意,只处理声明式函数,并且变量也只是进行了声明但未进行初始化以及赋值。

<script type="text/javascript">
    Fn(); //"执行了函数2",同名函数后者会覆盖前者
    function Fn(){
        //函数1 
        alert("执行了函数1"); 
    } 
    function Fn(){
        //函数2
        alert("执行了函数2"); 
    } 
</script>

<script type="text/javascript">
    Fn(); //"执行了声明式函数",在预编译期声明函数及被处理了,因此即便Fn()调用函数放在声明函数前也能执行。
    function Fn(){ 
        //声明式函数 
        alert("执行了声明式函数"); 
    } 
    var Fn = function(){ 
        //赋值式函数 
        alert("执行了赋值式函数"); 
    } 
</script>

理解了上面的几个术语,相信你们对JS的运行机制已经有了个大概的印象了,如今咱们来看个例子:

<script type="text/javascript">
    Fn(); 
    //浏览器报错:"undefined" 
</script> 
<script type="text/javascript"> 
    function Fn(){ 
       alert("执行了函数1"); 
    } 
</script>

JS引擎是按照代码块来顺序执行的,按照代码块来进行预处理和执行的,也就是说预处理的只是执行到的代码块的声明函数和变量,而对于还未加载的代码块,是无法进行预处理的,这也是边编译边处理的核心所在。

而根据HTML文档流的执行顺序,须要在页面元素渲染前执行的js代码应该放在前面的<script>代码块中,而须要在页面元素加载完后的js放在元素后面,body标签的onload事件是在最后执行的。

<script type="text/javascript">
    alert("first"); 
    function Fn(){ 
        alert("third"); 
    } 
</script> 

<script type="text/javascript"> 
    alert("second"); 
</script>
相关文章
相关标签/搜索