js引擎就是为读懂javascript代码,准确的给出代码运行结果的程序,这里不过多的研究引擎内部机制,只是探索js运行流程以及和浏览器关系。js引擎是浏览器的组成部分,浏览器引擎负责解析页面、渲染页面、Cookie管理、历史记录等等。JavaScript引擎通常是浏览器自行开发的,好比:IE9的Chakra、Firefox的 TraceMonkey、Chrome的V8等等。javascript
js引擎是单线程执行的,也就是说在同一时间只有一个线程在执行,而js中事件、计时器、异步回调都是浏览器帮助的,如onclick事件,js单线程加载时注册事件,浏览器会帮助咱们监听这个事件,好比o.onclick=function(){}(o为DOM对象等),当点击发生时:浏览器事件触发线程会为咱们把指定的事件处理程序添加到js引擎当中,js进程时间线空闲时,这段代码执行。java
js单线程执行,因此ajax、事件、settimeout、setinterval是由浏览器新开一个线程请求,当请求的状态变动时,若是先前已设置回调,这异步线程就产生状态变动事件放到JavaScript引擎的处理队列中等待处理。ajax
以下,浏览器引擎和js引擎:浏览器
以下,js进程时间线异步
JavaScript是一种描述型脚本语言,不一样于java等编译性语言,它不须要编译成中间语言,而是由浏览器进行动态地解析与执行,执行流程:函数
step 1. 读入第一个代码段spa
step 2. 作语法分析,有错则报语法错误(好比括号不匹配等),并跳转到step5。线程
step 3. 对var变量和function定义作“预解析”(永远不会报错的,由于只解析正确的声明)。code
step 4. 执行代码段,有错则报错(好比变量未定义)。对象
step 5. 若是还有下一个代码段,则读入下一个代码段,重复step2。
step6. 结束。
JavaScript中的代码块是指由<script>标签分割的代码段。例如:
<script type="text/javascript"> alert("代码段一"); </script> <script type="text/javascript"> alert("代码段二"); </script>
JS是按照代码块来进行编译和执行的,代码块间相互独立,但变量和方法共享。
<script type="text/javascript"> alert(str);//undefined alert("代码段一"); var test = "1"; </script> <script type="text/javascript"> alert("代码段二"); alert(test); //输出代码段一中变量值:1 </script>
JS中的函数定义分为两种:声明式函数与赋值式函数。
<script type="text/javascript"> function Fn(){ //声明式函数 } var Fn = function{ //赋值式函数 } </script>
声明式函数与赋值式函数的区别在于:在JS的预编译期,声明式函数将会先被提取出来,而后才按顺序执行js代码。
事实上,JS的解析过程分为两个阶段:预编译期(预解析)与执行期。
经过var关键字定义的变量进行预解析的时候:都是声明declare,无论它有没有赋值,都会赋值undefined
//代码块一 <script type="text/javascript"> alert(str);//浏览器报错,但并无弹出信息窗 </script> //代码块二 <script type="text/javascript"> alert(str); //undefined var str = "aaa"; </script> //js在预处理期对变量进行了声明处理,可是并无进行初始化与赋值,因此致使代码块二中的变量是unfiened的,而代码一中的变量是彻底不存在的,因此浏览器报错。
function进行预解析的时候,不只是声明并且还定义(define)了,可是它存储的数据的那个空间里面存储的是代码是字符串,没有任何意义,注意,只处理声明式函数,并且变量也只是进行了声明但未进行初始化以及赋值。
<script type="text/javascript"> Fn(); //"执行了函数2",同名函数后者会覆盖前者 function Fn(){ //函数1 alert("执行了函数1"); } function Fn(){ //函数2 alert("执行了函数2"); } </script> <script type="text/javascript"> Fn(); //"执行了声明式函数",在预编译期声明函数及被处理了,因此即便Fn()调用函数放在声明函数前也能执行。 function Fn(){ //声明式函数 alert("执行了声明式函数"); } var Fn = function(){ //赋值式函数 alert("执行了赋值式函数"); } </script>
理解了上面的几个术语,相信你们对JS的运行机制已经有了个大概的印象了,如今咱们来看个例子:
<script type="text/javascript"> Fn(); //浏览器报错:"undefined" </script> <script type="text/javascript"> function Fn(){ alert("执行了函数1"); } </script>
JS引擎是按照代码块来顺序执行的,按照代码块来进行预处理和执行的,也就是说预处理的只是执行到的代码块的声明函数和变量,而对于还未加载的代码块,是无法进行预处理的,这也是边编译边处理的核心所在。
而根据HTML文档流的执行顺序,须要在页面元素渲染前执行的js代码应该放在前面的<script>代码块中,而须要在页面元素加载完后的js放在元素后面,body标签的onload事件是在最后执行的。
<script type="text/javascript"> alert("first"); function Fn(){ alert("third"); } </script> <script type="text/javascript"> alert("second"); </script>