`

javascript运行机制之执行顺序详解

 
阅读更多

JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行。如果你不能理解javaScript语言的运行机制,或者简单地说,你不能掌握javascript的执行顺序,那你就犹如伯乐驾驭不了千里马,让千里马脱缰而出,四处乱窜。

那么JavaScript是怎么来进行解析的吗?它的执行顺序又是如何的呢?在了解这些之前,我们先来认识几个重要的术语:

1、代码块

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

 

1
2
3
4
5
6
<script type="text/javascript">
      alert("这是代码块一");
</script>
<script type="text/javascript">
      alert("这是代码块二");
</script>

 

JS是按照代码块来进行编译和执行的,代码块间相互独立,但变量和方法共享。什么意思呢? 举个例子,你就明白了:

 

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
      alert(str);//因为没有定义str,所以浏览器会出错,下面的不能运行
      alert("我是代码块一");//没有运行到这里
      var test = "我是代码块一变量";
</script>
<script type="text/javascript">
      alert("我是代码块二"); //这里有运行到
      alert(test); //弹出"我是代码块一变量"
</script>

上面的代码中代码块一中运行报错,但不影响代码块二的执行,这就是代码块间的独立性,而代码块二中能调用到代码一中的变量,则是块间共享性。

 

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

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

 

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
     function Fn(){ //声明式函数
             
     }
         
     var Fn = function{  //赋值式函数
             
     }
</script>

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

 

3、预编译期与执行期

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

预编译期JS会对本代码块中的所有声明的变量和函数进行处理(类似与C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。

 

1
2
3
4
5
6
7
8
9
10
<script type="text/javascript">
     Fn();  //执行结果:"执行了函数2",同名函数后者会覆盖前者
     function Fn(){ //函数1
        alert("执行了函数1");
     }
         
     function Fn(){  //函数2
        alert("执行了函数2");
     }
</script>
1
2
3
4
5
6
7
8
9
10
<script type="text/javascript">
      Fn();  //执行结果:"执行了声明式函数",在预编译期声明函数及被处理了,所以即使Fn()调用函数放在声明函数前也能执行。
      function Fn(){ //声明式函数
         alert("执行了声明式函数");
      }
         
      var Fn = function(){  //赋值式函数
         alert("执行了赋值式函数");
      }
</script>
1
2
3
4
5
6
7
8
9
10
//代码块一
<script type="text/javascript">
      alert(str);//浏览器报错,但并没有弹出信息窗
</script>
//代码块二
<script type="text/javascript">
      alert(str); //弹窗"undefined"
      var str = "aaa";
</script>
//js在预处理期对变量进行了声明处理,但是并没有进行初始化与赋值,所以导致代码块二中的变量是unfiened的,而代码一中的变量是完全不存在的,所以浏览器报错。

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

 

 

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

为什么运行上面的代码浏览器会报错呢?声明函数不是会在预处理期就会被处理了吗,怎么还会找不到Fn()函数呢?其实这是一个理解误点,我们上面说了JS引擎是按照代码块来顺序执行的,其实完整的说应该是按照代码块来进行预处理和执行的,也就是说预处理的只是执行到的代码块的声明函数和变量,而对于还未加载的代码块,是没法进行预处理的,这也是边编译边处理的核心所在。

 

现在,让我们来总结整理下:

step 1. 读入第一个代码块。

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

step 3. 对var变量和function定义做“预编译处理”(永远不会报错的,因为只解析正确的声明)。

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

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

step6. 结束。

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

 

1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/javascript">
    alert("first");
    function Fn(){
        alert("third");
    }
</script>
 
     
 
<script type="text/javascript">
    alert("second");
</script>
分享到:
评论

相关推荐

    JavaScript运行机制之事件循环(Event Loop)详解

    在单线程模型中,JavaScript的运行机制围绕着任务队列(task queue)展开。所有的任务都会被放入主线程执行,当执行栈(execution context stack)为空时,主线程会读取任务队列,并按先进先出(FIFO)的顺序执行...

    实例详解JavaScript中setTimeout函数的执行顺序

    关于javascript的运行机制大家都应该有所了解了吧,其实javascript是一个单线程的机制,但是因为队列的关系它的表现会让我们感觉是一个多线程的错觉。下面这篇文章通过实例主要给大家介绍了关于JavaScript中...

    详解JavaScript 的执行机制

    JavaScript的执行机制是该语言特性的核心之一,掌握其运行原理对于开发高质量、高性能的Web应用至关重要。下面将从JavaScript单线程的本质、事件循环机制、宏任务与微任务的处理、以及setTimeout和setInterval的工作...

    Javascript 引擎工作机制详解

    JavaScript引擎是JavaScript代码得以运行的基础,它负责解释和执行代码。在深入理解JavaScript引擎工作机制时,我们需要掌握一些关键概念,如执行环境栈、全局对象、执行环境、变量对象、活动对象、作用域和作用域链...

    【JavaScript源代码】详解JavaScript中的执行上下文及调用堆栈.docx

    JavaScript中的执行上下文和调用堆栈是理解JS运行机制的关键概念。执行上下文是代码在特定环境中运行的抽象表示,它定义了变量、函数以及`this`关键字的行为。执行上下文主要有三种类型:全局执行上下文(默认的运行...

    js 程序执行与顺序实现详解

    它的主要特点之一就是支持事件驱动编程和异步编程,然而在其核心运行机制上,JavaScript是单线程的。它通过一个任务队列来管理事件和函数的执行顺序,确保在特定时间只有一个代码块在执行。这种机制虽然在现代浏览器...

    JavaScript提升机制Hoisting详解

    解析后的AST会被转化为可执行代码,这使得JavaScript引擎能够理解和运行代码。 现在,我们来看JavaScript中的声明和赋值。以`var age = 10;`为例,实际上在JavaScript中,这段代码相当于以下两个步骤: 1. **隐式...

    如何通过setTimeout理解JS运行机制详解

    总之,JavaScript的运行机制基于单线程、事件驱动和任务队列,理解这些概念对于编写高性能的异步代码至关重要。`setTimeout`的执行是在当前任务完成后,并且只有在所有微任务执行完毕后才会进行,这就解释了为何它在...

    Js中async/await的执行顺序详解

    在这个例子中,当`test()`函数运行到`await testSometing()`时,`testSometing`立即执行并打印"执行testSometing",然后由于`await`,`test()`函数的执行暂停,控制权交给后续的代码。此时,`promise`开始执行并打印...

    【JavaScript源代码】JS难点同步异步和作用域与闭包及原型和原型链详解.docx

    在JavaScript中,同步执行意味着代码按照顺序依次运行,等待每一个任务完成后再进行下一个任务。而异步执行则是非阻塞的,它允许代码在等待某个操作(如网络请求)完成的同时,继续执行其他任务。异步执行通常采用回...

    javascript基本知识

    ### JavaScript基本知识详解 #### 一、什么是JavaScript JavaScript(简称JS)是一种具有函数优先特性的轻量级、解释型或即时编译型的脚本语言。作为一种弱类型的编程语言,它允许开发者在声明变量时无需指定具体...

    《JavaScript异步编程》PDF版本下载.txt

    1. **同步执行**:代码按照顺序执行,当前的操作必须完成才能执行下一条语句。 2. **异步执行**:当前的操作启动后,不需要等待其完成就可以执行后续代码。当该操作完成后,通过回调函数、事件、Promise等方式通知...

    JavaScript反射与依赖注入实例详解

    在JavaScript中,反射允许我们在运行时检查对象的属性、方法、构造函数等信息,甚至可以动态地调用方法或修改对象的状态。例如,通过`Object.getOwnPropertyDescriptor`和`Object.keys`等内置函数,我们可以获取对象...

    韩顺平十天javascript全套笔记(整理版)

    ### 韩顺平十天JavaScript全套笔记知识点详解 #### JavaScript基本概念与应用领域 - **JavaScript简介**:JavaScript(简称JS)是一种轻量级、解释型或即时编译型的编程语言。它通常用于增强网页的交互性,并且...

    arcgis for javascript

    《ArcGIS for JavaScript 4.5:离线部署与应用开发详解》 ArcGIS for JavaScript 是Esri公司推出的一款强大的地图服务开发库,它允许开发者使用JavaScript语言在Web上创建丰富的地理信息系统(GIS)应用程序。在...

    详解JavaScript中常用的函数类型

    这种函数创建方式类似于Java中的类反射机制,允许我们在运行时根据字符串来创建和执行函数。这对于需要根据运行时条件来创建函数的应用场景非常有用,因为它提供了一种在程序运行时改变程序行为的方法。例如,可以...

Global site tag (gtag.js) - Google Analytics