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代码应该放在<body>前面的<script>代 码块中,而需要在页面元素加载完后的js放在</body>元素后面,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> <body onload="Fn()"> </body> <script type="text/javascript"> alert("second"); </script> |
javascript 执行顺序详解的更多相关文章
- Unity 继承MonoBehaviour脚本 执行顺序 详解
先看结果 Awake ->OnEnable-> Start ->-> FixedUpdate-> Update -> LateUpdate ->OnGUI ...
- javascript运行机制之执行顺序详解(转)
转自http://www.admin10000.com/document/3385.html JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言, ...
- JavaScript 运行机制之执行顺序详解
JavaScript是一种描述型脚本语言,它不同于 Java 或 C# 等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解 JavaScript 语言的运行机制 ...
- async/await 执行顺序详解
随着async/await正式纳入ES7标准,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 ...
- React生命周期执行顺序详解
文章内容转载于https://www.cnblogs.com/faith3/p/9216165.html 一.组件生命周期的执行次数是什么样子的??? 只执行一次: constructor.compo ...
- ASP.NET 页面执行顺序详解
今天整理了一下ASP执行过程,从.net页码的执行周期开始做一个详细的了解.我重写了页面的绝大多数方法.然后加载执行.所得的顺序如下. 方法是每个重写的事件中都输出一个字符,按字符打印出来的先后判断事 ...
- JS中的async/await的执行顺序详解
虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(如果对async/await不熟悉 ...
- 【Node.js】Event Loop执行顺序详解
本文基于node 0.10.22版本 关于EventLoop是什么,请看阮老师写的什么是EventLoop 本文讲述的是EventLoop中的执行顺序(着重讲setImmediate, setTime ...
- Python装饰器执行顺序详解
探究多个装饰器执行顺序 装饰器是Python用于封装函数或代码的工具,网上可以搜到很多文章可以学习,我在这里要讨论的是多个装饰器执行顺序的一个迷思. 疑问 大部分涉及多个装饰器装饰的函数调用顺序时都会 ...
随机推荐
- Hibernate配置文件中映射元素详解
对象标识符号 在关系数据库表中,主键(Primary Key)用来识别记录,并保证每条记录的唯一性.在Java语言中,通过比较两个变量所引用对象的内存地址是否相同,或者比较两个变量引用的对象值是否相同 ...
- CSU 1120 病毒
最长公共上升子序列(LCIS) 裸的算法题. 动态规划: 两组数组a[n].b[m]. f[i][i]表示以a[i].b[j]结尾的两个数组的LCIS. 转移方程: a[i]!=b[j] : f[i] ...
- 关于android:focusable属性
http://www.cnblogs.com/Gaojiecai/archive/2013/06/18/3142783.html Android属性 android:focusableInTouchM ...
- hdu 1599 find the mincost route
http://acm.hdu.edu.cn/showproblem.php?pid=1599 floyd找最小环. #include <cstdio> #include <cstri ...
- Qt5.3企业版和开源版功能区别
一: Charts Charts是QT提供的图表模块.他提供了非常简便的APIs来绘制令人惊叹的Line, Spline,Area,Scatter,Pie,Donut,Bar,Polar和Box-an ...
- Windows资源文件里VarFileInfo的Translation(EXE的语言描述信息)
/* The following line should only be modified for localized versions. */ /* It consists of any numbe ...
- 10个工具让你的 shell 脚本更强大
10个工具让你的 shell 脚本更强大 很多人误以为shell脚本只能在命令行下使用.其实shell也可以调用一些GUI组件,例如菜单,警告框,进度条等等.你可以控制最终的输出,光标位 置还有各种输 ...
- 通过实现Comparable接口结合TreeSet来对对象自动排序
经过会遇到这样的情况,对于某个对象数组或者链表要按照一定的规则进行排序,那么我们该怎么做呢? 如遇到这样的需求: 1.需求1 对于学生对象按照年龄进行排序,年龄小的排在前面. 单单看到这样的需求,实现 ...
- 【转】ffserver用法小结
我们可以通过ffserver以及ffmpeg做一个简单的视频监控系统,ffserver用于视频的转发调度,ffmpeg用于转码 而对于ffserver最基本也是最重要的就是对它的ffserver.co ...
- Linux TCP/IP 协议栈之 Socket 的实现分析(一)
内核版本:2.6.37参考[作者:kendo的文章(基于内涵版本2.6.12)] 第一部份 Socket套接字的创建 socket 并不是 TCP/IP协议的一部份. 从广义上来讲,socket 是U ...