`
wangyanlong0107
  • 浏览: 499717 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

【转】javascript运行机制之执行顺序详解

 
阅读更多

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

       本文地址:http://blog.csdn.net/chen_zw/article/details/18502937

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

      1、代码块

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

 

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <script type="text/javascript">  
  2.       alert("这是代码块一");  
  3. </script>  
  4. <script type="text/javascript">  
  5.       alert("这是代码块二");  
  6. </script>  

 

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

 

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

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

 

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

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

 

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <script type="text/javascript">  
  2.      function Fn(){ //声明式函数  
  3.               
  4.      }  
  5.           
  6.      var Fn = function{  //赋值式函数  
  7.               
  8.      }  
  9. </script>  

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

 

         3、预编译期与执行期

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

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

 

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

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

 

 

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <script type="text/javascript">  
  2.       Fn();  //浏览器报错:"undefined"  
  3. </script>  
  4. <script type="text/javascript">  
  5.       function Fn(){ //函数1  
  6.           alert("执行了函数1");  
  7.       }  
  8. </script>  

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

 

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

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

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

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

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

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

              step6. 结束。

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

 

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <script type="text/javascript">  
  2.     alert("first");  
  3.     function Fn(){  
  4.         alert("third");  
  5.     }  
  6. </script>  
  7. <body onload="Fn()">  
  8.       
  9. </body>  
  10. <script type="text/javascript">  
  11.     alert("second");  
  12. </script>  
分享到:
评论

相关推荐

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

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

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

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

    详解JavaScript 的执行机制

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

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

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

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

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

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

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

    Javascript 引擎工作机制详解

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

    JavaScript提升机制Hoisting详解

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

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

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

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

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

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

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

    javascript基本知识

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

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

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

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

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

    async/await让异步操作同步执行的方法详解

    在示例中,`fn1`和`fn2`虽然先执行,但`setTimeout`内的回调函数会在延迟后才运行,导致输出顺序不符合预期。即使将`setTimeout`的延迟时间设为0,由于事件循环机制,它依然会在所有同步任务完成后才执行。 2. **...

    单线程JavaScript实现异步过程详解

    JavaScript的单线程特性意味着代码按顺序执行,但这并不妨碍它实现异步功能。这是因为浏览器为JavaScript提供了多线程环境。例如,JavaScript引擎(主线程)负责执行代码,而其他辅助线程如定时器线程则处理异步任务...

Global site tag (gtag.js) - Google Analytics