浅谈JavaScript 的执行顺序


Posted in Javascript onAugust 07, 2015

虽然现代浏览器可以并行的下载JavaScript(部分浏览器),但考虑到JavaScript的依赖关系,他们的执行依然是按照引入顺序进行的。

本文章记录本人在学习 JavaScript 中看书理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习。

在 html 文档中的执行顺序

js代码执行顺序比较的形象,用户可以直观的感受这种执行顺序。但是,js代码的执行顺序是比较复杂的。有时候我们会把js代码写在html里面,而html文档在浏览器中解析的过程是这样:浏览器按照文档流从上到下逐步解析页面结构和信息。js代码作为嵌入的脚本也算做html文档的组成部分,因此,js代码在装载时的执行顺序也是根据脚本标签<script>的出现来顺序来决定。(下面一个栗子)

<!DOCTYPE html>
<script>
  console.log("顶部脚本");
</script>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script>
    console.log("头部脚本");
  </script>
</head>
<body>
  <script>
    console.log("页面脚本");
  </script>
</body>
</html>
<script>
  console.log("底部脚本");
</script>

还有对于通过脚本标签<script>的src属性导入的外部js文件脚本,它也将按照其语句出现的顺序来执行,而且执行过程是文档装载的一部分,不会因为是外部js文件而延期执行。

// 先加载 b.js 并且执行里面的代码
<script src="b.js"></script>
// 然后在按顺序执行下面的代码
<script>
  console.log(1);
</script>

预编译

当js引擎解析的时候,它会在预编译对所有声明的变量和函数进行处理。

变量提升

console.log(a); // undefined
var a = 1;
console.log(a); // 1

预解析函数

f(); // 1
function f() {
  console.log(1);
};

详细:javascript变量声明提升(hoisting)

分块执行代码

js是按块执行代码的,所谓代码块就是使用<script>标签分隔的代码段。(下面一个栗子)

<script>
  // 代码段1
  var a = 1;
</script>
<script>
  // 代码段2
  function f() {
    console.log(1);
  };
</script>

因为js是按代码块来执行的。浏览器在解析html文档流的时候,如果遇到一个<script>标签,则js会等到这个代码块都加载完之后再对代码进行预编译,然后在执行。执行完毕后,浏览器会继续解析西门的html文档流,同时js也准备好处理下一个代码块。

有个小坑,由于js是按块执行的,因此在一个js块中调用后面块声明的变量或者函数就会提示语法错误。但是不同块都属于一个全局作用域,也就是说,块之间的变量和函数是可以共享的。(下面一个栗子)

<script>
  // 代码段1
  console.log(a);
  f();
</script>
<script>
  // 代码段2
  var a = 1;
  function f() {
    console.log(1);
  };
</script>

由于js是按块处理代码,同时又遵循html文档流的解析顺序,因此在上面的栗子中会看到语法错误。但是,在文档流加载完毕后再次访问就不会出现这种错误了。(下面一个栗子)

<script>
  window.onload = function(){ // 页面初始化事件处理函数
    // 代码段1
    console.log(a);
    f();
  }
</script>
<script>
  // 代码段2
  var a = 1;
  function f() {
    console.log(1);
  };
</script>

还有为了安全起见,一般在页面初始化完毕之后才允许js代码执行,这样就可以避免一些网速对js执行的影响。同时,也避开了html文档流对js执行的限制。

综上所述,javascript在执行时的步骤是:

1、先读入第一段代码块

2、对代码块进行语法分析,如果出现语法错误,直接执行第5步骤

3、对var变量和function定义的函数进行“预编译处理”(赋值式函数是不会进行预编译处理的)

4、执行代码块,有错则报错

5、如果还有下一段代码块,则读入下一段代码块,重复步骤2

6、结束

Javascript 相关文章推荐
javascript一点特殊用法
May 28 Javascript
javascript 操作文件 实现方法小结
Jul 02 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
Jul 15 Javascript
JavaScript字符串String和Array操作的有趣方法
Dec 18 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
Jan 05 Javascript
javascript 判断一个对象为数组的方法
May 03 Javascript
Angular2 组件通信的实例代码
Jun 23 Javascript
Angular2使用vscode断点调试ts文件的方法
Dec 13 Javascript
vue-cli3.0配置及使用注意事项详解
Sep 05 Javascript
js验证密码强度解析
Mar 18 Javascript
JavaScript React如何修改默认端口号方法详解
Jul 28 Javascript
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
Apr 30 Vue.js
javascript封装 Cookie 应用接口
Aug 07 #Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
Aug 07 #Javascript
jQuery与getJson结合的用法实例
Aug 07 #Javascript
《JavaScript函数式编程》读后感
Aug 07 #Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
Aug 07 #Javascript
jquery实现先淡出再折叠收起的动画效果
Aug 07 #Javascript
C++中的string类的用法小结
Aug 07 #Javascript
You might like
PHP中输出转义JavaScript代码的实现代码
2011/04/22 PHP
解析PHP高效率写法(详解原因)
2013/06/20 PHP
PHP的基本常识小结
2013/07/05 PHP
遭遇php的in_array低性能问题
2013/09/17 PHP
简单谈谈PHP vs Node.js
2015/07/17 PHP
PHP简单计算两个时间差的方法示例
2017/06/20 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
2018/06/13 PHP
Javascript中call与apply的学习笔记
2014/09/22 Javascript
原生JS和JQuery动态添加、删除表格行的方法
2015/05/28 Javascript
JS表格组件神器bootstrap table详解(强化版)
2016/05/26 Javascript
实例分析浏览器中“JavaScript解析器”的工作原理
2016/12/12 Javascript
AngularJS中的缓存使用
2017/01/11 Javascript
node.js程序作为服务并在windows下开机自启动(用forever)
2017/03/29 Javascript
Angular4学习笔记之根模块与Ng模块
2017/09/09 Javascript
angular4模块中给标签添加背景图的实现方法
2017/09/15 Javascript
[26:21]浴火之凤-TI4世界冠军Newbee战队纪录片
2014/08/07 DOTA
[44:50]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第二局
2016/02/26 DOTA
[01:07:15]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第二场 1月25日
2021/03/11 DOTA
Python的爬虫程序编写框架Scrapy入门学习教程
2016/07/02 Python
浅谈python中对于json写入txt文件的编码问题
2018/06/07 Python
python使用flask与js进行前后台交互的例子
2019/07/19 Python
python多进程间通信代码实例
2019/09/30 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
Max&Co官网:意大利年轻女性时尚品牌
2017/05/16 全球购物
美国领先的家庭健康检测试剂盒提供商:LetsGetChecked
2019/03/18 全球购物
美国尼曼百货官网:Neiman Marcus
2019/09/05 全球购物
意大利和国际最佳时尚品牌:Drestige
2019/12/28 全球购物
医学毕业生自荐信
2013/10/11 职场文书
动物学专业毕业生求职信
2013/10/11 职场文书
工伤事故赔偿协议书范文
2014/09/24 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
幼儿园园长工作总结2015
2015/05/25 职场文书
八年级物理教学反思
2016/02/19 职场文书
基于nginx实现上游服务器动态自动上下线无需reload的实现方法
2021/03/31 Servers
golang 实现并发求和
2021/05/08 Golang
PHP正则表达式之RCEService回溯
2022/04/11 PHP