浅谈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 相关文章推荐
[转]JS宝典学习笔记
Feb 07 Javascript
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
May 24 Javascript
javascript通过class来获取元素实现代码
Feb 20 Javascript
js中的scroll和offset 使用比较的实例与分析
Sep 29 Javascript
简单的js表单验证函数
Oct 28 Javascript
AngularJS语法详解(续)
Jan 23 Javascript
JavaScript计算两个日期时间段内日期的方法
Mar 16 Javascript
Node.js实用代码段之正确拼接Buffer
Mar 17 Javascript
微信小程序 css使用技巧总结
Jan 09 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
Mar 30 Javascript
js实现方块上下左右移动效果
Aug 17 Javascript
微信小程序input框中加入小图标的实现方法
Jun 19 Javascript
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生成指定随机字符串的简单实现方法
2015/04/01 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
2019/05/08 PHP
php设计模式之中介者模式分析【星际争霸游戏案例】
2020/03/23 PHP
javascript 支持ie和firefox杰奇翻页函数
2008/07/22 Javascript
JQuery的Validation插件中Remote验证的中文问题
2010/07/26 Javascript
jquery.simple.tree插件 更简单,兼容性更好的无限树插件
2010/09/03 Javascript
一张表格告诉你windows.onload()与$(document).ready()的区别
2014/05/16 Javascript
JavaScript插件化开发教程 (三)
2015/01/27 Javascript
在JavaScript应用中实现延迟加载的方法
2015/06/25 Javascript
JavaScript实现Java中Map容器的方法
2016/10/09 Javascript
Boostrap实现的登录界面实例代码
2016/10/09 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
微信小程序 textarea 详解及简单使用方法
2016/12/05 Javascript
JavaScript中定义对象原型的两种使用方法
2016/12/15 Javascript
jQuery实现遮罩层登录对话框
2016/12/29 Javascript
ztree实现权限横向显示功能
2017/05/20 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
2018/05/07 Javascript
nodejs读取本地中文json文件出现乱码解决方法
2018/10/10 NodeJs
JavaScript实现无限级递归树的示例代码
2019/03/29 Javascript
vue移动端屏幕适配详解
2019/04/30 Javascript
浅析Python编写函数装饰器
2016/03/18 Python
Django实现自定义404,500页面教程
2017/03/26 Python
Django视图之ORM数据库查询操作API的实例
2017/10/27 Python
python 日期操作类代码
2018/05/05 Python
Python基础知识点 初识Python.md
2019/05/14 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
python3使用GUI统计代码量
2019/09/18 Python
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
银行自荐信范文
2013/10/07 职场文书
计算机科学与技术应届生求职信
2013/11/07 职场文书
家长写给孩子的评语
2014/04/18 职场文书
禁止高声喧哗的标语
2014/06/11 职场文书
vue实现简单数据双向绑定
2021/04/28 Vue.js
Python下载商品数据并连接数据库且保存数据
2022/03/31 Python
mysql查询结果实现多列拼接查询
2022/04/03 MySQL