转载来自:https://blog.csdn.net/wnvalentin/article/details/79769393
1. 按块加载并执行
对于一个HTML文档,浏览器的解析顺序为:按照文档流,从上到下逐步解析页面的结构。JavaScript代码作为通过标签嵌入或引入的脚本,也HTML文档的组成部分。因此,JavaScript代码在装载时的执行顺序也是根据脚本标签<script>的出现顺序来确定的。
但是,浏览器加载JavaScript时有个特点,那就是载入之后立即就会执行(先编译后执行),因为JavaScript可能会影响DOM树的结构,所以浏览器在执行完后才能继续加载下面的HTML内容。也就是说,浏览器下载并执行JavaScript的过程会阻塞DOM树的继续建立。所以,引入的多个js文件,会按顺序分开执行。同样的,对于不同<script>标签嵌入的JavaScript代码,也会分开执行。同一组<script>标签包括的代码就是一个代码块。后引入的JavaScript文件可以调用先引入的JavaScript文件的资源,下面的代码块可以访问上面代码块的资源,反之则不行。
由于JavaScript通常需要操作DOM,所以,一般把JavaScript放在</body>前或者文档结尾处引入。若需要在<head>中引入,可以通过修改window.onload或者document.ready事件,强制等到DOM加载完成后再执行相关函数。
2. 先预处理后执行
在一个JavaScript文件或一个JavaScript代码块的内部,浏览器会先对代码进行预处理(编译),然后再执行。
预处理会跳过执行语句,只处理声明语句,同样也是按从上到下按顺序进行的。包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。 即使声明是在调用的下方进行的,但浏览器仍然先声明再调用(执行),这个现象叫做“提升”。所以,即便一个函数的声明在下方,在前面仍然可以正常执行这个函数。
注意1:对于声明并赋值的语句,例如 var a = 1,在预处理阶段会把这句话拆成两句:
-
var a;
-
a = 1;
也就是说,赋值或其他逻辑运算是在执行阶段进行的,在预处理阶段会被忽略。
注意2:(1)函数声明的提升优先于变量声明的提升;(2)重复的var声明会被忽略掉,但是重复的function声明会覆盖掉前面的声明。
在预处理阶段,声明的变量的初始值是undefined, 采用function声明的函数的初始内容就是函数体的内容。
3. 执行顺序
完成预处理之后,JavaScript代码会从上到下按顺序执行逻辑操作和函数的调用。