`
wangyanlong0107
  • 浏览: 480404 次
  • 性别: 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中setTimeout函数的执行顺序

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

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

    序 setTimeout()函数:用来指定某个函数或某段...解析:无论setTimeout的执行时间是0还是1000,结果都是先输出3后输出2,这就是面试官常常考查的js运行机制的问题,接下来我们要引入一个概念,JavaScript 是单线程的。

    php网络开发完全手册

    8.5.1 顺序查找 127 8.5.2 二分法查找 128 8.5.3 使用array_search函数进行查找 129 8.5.4 线性表的入栈与出栈 129 8.5.5 数组的合并 131 8.5.6 数组的拆分 133 8.5.7 随机排序 134 8.6 小结 135 第9章 PHP程序调试 ...

    详解js的异步编程技术的方法

    基于浏览器的事件轮询机制(以及Node.js中的事件轮询机制),JavaScript常常会运行在异步环境中。由于JavaScript本身语言的特性(不需要程序员操控线程/进程),在js中解决异步化编程的方法就显得相当重要。可以说一...

    python入门到高级全栈工程师培训 第3期 附课件代码

    09 继承顺序之mro线性顺序列表 10 在python2中的继承顺序是什么 11 在子类中调用父类方法 12 super调用父类的方法 13 选择系统作业讲解 第26章 01 学生自主复习 02 分享列表 03 多态 04 封装 05 面向对象概念总结 ...

    史上最全韩顺平传智播客PHP就业班视频,10月份全集

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    史上最全传智播客PHP就业班视频课,8月份视频

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    史上最全韩顺平传智播客PHP就业班视频,9月份全集

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    (全)传智播客PHP就业班视频完整课程

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    韩顺平PHP JS JQUERY 所有视频下载种子 货真价实

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    庖丁解牛纵向切入ASP.NET 3.5控件和组件开发技术.pdf

    如果扎实地掌握了asp.net控件的运行机制,开发一个页面级的asp.net应用程序会变得非常简单。本书宗旨就是让开发人员真正理解asp.net技术,帮助开发人员提高asp.net开发的技术水平。学完本书后您不仅能够掌握控件开发...

    庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术

    3.2 控件呈现顺序 28 3.3 render呈现控件的几种方式 30 3.3.1 使用htmltextwriter类输出 30 3.3.2 直接输出html标签 32 3.3.3 使用服务器控件的rendercontrol方法 33 3.4 addattributestorender方法 34 3.5 ...

    asp.net知识库

    asp.net 运行机制初探(httpModule加载) 利用反射来查看对象中的私有变量 关于反射中创建类型实例的两种方法 ASP.Net应用程序的多进程模型 NET委托:一个C#睡前故事 [推荐] - [原创] Microsoft .NET策略及框架概述 ...

    庖丁解牛 纵向切入ASP.NET 3.5控件和组件开发 part1

    8.2 clientscriptmanager类功能详解 301 8.2.1 registerarraydeclaration方法 301 8.2.2 registerclientscriptblock方法 302 8.2.3 registerclientscriptinclude方法 303 8.2.4 registerclientscriptresource...

    庖丁解牛 纵向切入ASP.NET 3.5控件和组件开发 part2

    8.2 clientscriptmanager类功能详解 301 8.2.1 registerarraydeclaration方法 301 8.2.2 registerclientscriptblock方法 302 8.2.3 registerclientscriptinclude方法 303 8.2.4 registerclientscriptresource...

    亮剑.NET深入体验与实战精要2

    1.4 .NET的面向对象之门 27 1.4.1 继承——“子承父业” 28 1.4.2 委托——“任务书” 35 1.4.3 事件——“年终分红” 42 1.4.4 反射——“解剖” 49 1.5 .NET开发几把小刀 52 1.5.1 using之多变身 52 1.5.2 @符号的...

    亮剑.NET深入体验与实战精要3

    1.4 .NET的面向对象之门 27 1.4.1 继承——“子承父业” 28 1.4.2 委托——“任务书” 35 1.4.3 事件——“年终分红” 42 1.4.4 反射——“解剖” 49 1.5 .NET开发几把小刀 52 1.5.1 using之多变身 52 1.5.2 @符号的...

    Tcl_TK编程权威指南pdf

    Tcl和与之关联的图形用户界面工具包(Tk)是由加州大学的John Ousterhout教授设计并编写的。尽管它是个商用软件包,但你也可以在Internet上找到它(见第VII页),而且可以在自己的应用程序中自由使用这个软件包。Tcl解释...

Global site tag (gtag.js) - Google Analytics