在HTML里面使用javaScript有两种方式:java
1: 经过<script>元素直接嵌入一段代码 2: 经过<script>元素的src属性引入外部js文件
当咱们经过<script>元素引入外部js文件的时候,<script>元素自己的两个属性对整个页面的解析,js文件自己的下载和执行都会产生影响,这两个属性就是:defer, async
接下来的文章对js全部可能的状况一一总结
1: 经过<script>元素直接嵌入一段代码浏览器
<script> (function(){alert('hello')})() </script> <script> (function(){alert('javaScript')})() </script>
以上的一段代码,若是是放在<head>里面,那么页面的解析(页面的解析是遇到<body>开始)就要等这两段script执行完了才会开始,而且规定那个先出现就先执行哪一个,因此以上代码会先执行alert('hello')
,再执行alert('javaScript')
异步
若是上面的代码是放在body里面, 那上面代码的存在则会直接致使页面的解析,要等这段js代码执行完了,再继续页面解析的工做。async
3:经过<script>元素的src属性引入外部js文件,可是没有defer和asyncspa
<script src="./static/js/a.js"></script> <script src="./static/js/b.js"></script>
以上的状况浏览器会按照文件出现的前后顺序去下载和执行代码,意思就是b.js会在a.js执行完以后再执行。
若是上述代码是放在body里面,那么它也是阻塞的,若是用图表示的话就是:code
**2:经过<script>元素的src属性引入外部js文件,可是有async事件
<script src="./static/js/a.js" async></script> <script src="./static/js/b.js" async></script>
遇到带有async属性的<script>标签,表示这个js文件的下载是异步的,意思就是它不会阻塞页面的解析,可是它一旦下载完,他的js代码就会被当即执行。若是用图表示的话就是:图片
从这个图对比上面的第2种状况,能够看出,在下载js文件的时候,页面的解析依然是在执行的,只是下载完以后js的执行会阻塞页面的解析。
若是遇到多个带async的<script>标签,那么他们的执行顺序是没法保证的。就像上面的代码,没法保证a.js必定会在b.js前面执行。ip
4: 2:经过<script>元素的src属性引入外部js文件,可是没有deferit
<script src="./static/js/a.js" defer></script> <script src="./static/js/b.js" defer></script>
先来看一下defer的图像表示:
defer只在<script>经过src去引入外部js文件时候才会起做用。当<script>的type=module的时候,defer也会被忽略,由于type=module的时候,<script>会按照defer那样的特性工做。
带有defer的<script>元素的下载一样不会阻塞页面的解析,而且它的执行也不会,由于它是等页面解析完成以后再执行的。若是遇到多个带defer的<script>元素,js代码的执行也会按照定义的顺序去执行。可是这两个脚本都会先于DOMContentLoaded事件执行。
**BUT, 在现实世界中,带defer的script不必定按照顺序执行,也不必定会先于DOMContentLoaded事件执行。因此,呵呵。