JS脚本解析与执行顺序
来源:互联网 发布:淘宝二手可信吗 编辑:程序博客网 时间:2024/05/22 03:10
在了解JavaScript具体是怎样解析之前,我们先来了解几个重要的概念:
1.代码块
JavaScript中的代码块是指由
<script type="text/javascript"> alert("这是代码块一");</script><script type="text/javascript"> alert("这是代码块二");</script>
JS是按照代码块来进行编译和执行的,代码块间相互独立,但变量和方法共享。
浏览器在解析html文档流的时候,如果遇到一个<script>
标签,则JS会等到这个代码块加载完之后再对代码进行预编译,然后再执行。执行完毕后,浏览器会继续解析html文档流,同时js也准备好处理下一个代码块。由于JS是按块执行的,因此在一个JS块中调用后面声明的变量或者函数就会提示语法错误。但是不同块都属于一个全局作用域,也就是说,块之间的变量和函数可以共享。
举例:
<title>JS执行顺序</title> <script type="text/javascript"> alert("这是代码块1");//先弹出"这是代码块1" alert(str);//因为str没有定义,所以浏览器会报错,后面代码不能运行 alert("haha"); var test = "我是代码块一中的变量"; </script> <script type="text/javascript"> alert("我是代码块二");//弹出"我是代码块二" alert(test);//弹出"我是代码块一中的变量" </script>
代码块一运行报错,但是不影响代码块二的执行,这就是代码块间的独立性,而代码块二能调用到代码块一中的=变量,即为块间的共享性。
2.函数声明与函数赋值
JS函数定义分为两种:韩顺声明和函数赋值式。
<script type="text/javascript"> function Fn(){ //函数声明 } var Fn = function(){ //赋值式函数 }</script>
这两者在JS的与编译器的区别会体现出来。下面就来说一说预编译。
3.预编译器与执行期
JS的解析分为两个阶段:预编译期(预处理期)与执行期
预编译期JS会对本代码中所有声明的变量和函数进行处理(类似于c语言的编译),但是处理函数只是处理声明式函数,将其提前,而变量也只是进行了声明但是并未进行初始胡以及赋值。
举例:
<script type="text/javascript"> Fn();//"执行了声明式函数",在预编译期函数被处理了 function Fn(){//声明式函数 alert(""执行了声明式函数); } var Fn = function(){//赋值式函数 alert("执行了赋值式函数"); }</script>
了解了以上几个概念,下面来看一个例子:
<script type="text/javascript"> Fn();//Fn is not defined </script> <script type="text/javascript"> function Fn(){ alert("执行了函数1"); } </script>
代码块一在执行函数Fn时报错,这是为什么?
原因在于JS引擎是按照代码块来顺序执行的,完整的说是按照代码块来进行预处理和执行的,也就是预处理的只是执行到代码块的声明函数和变量,对于还未加载的代码块,没有办法进行预处理。
JS是单线程的
举例:
function foo(){ console.log("first"); setTimeout((function(){console.log('second');}),5);}for(var i = 0;i<10000000;i++){ foo();}
执行结果会首先会全部输出first,然后全部输出second.
JS运行在浏览器中是单线程的,每一个window的一个JS线程,既然是单线程的,在某个特定的时刻,只有特定的代码能够执行,并且阻塞其他代码的执行。而浏览器是事件驱动的,浏览器中很多行为是异步的,会创建事件放在执行队列中。Javascript引擎是单线程处理它的任务队列,所以当多个事件触发时,会依次放入队列,然后一个个响应(所以上面的代码是5ms后把输出second的任务加入队列中),而当前有任务,所以只能等到1000000个first输出完成后才会输出second。
浏览器是多线程的
虽然JS运行在浏览器中,是单线程的,但是浏览器不是单线程的。浏览器中的很多异步行为都是由浏览器新开一个线程去完成的。Javascript引擎线程是浏览器多个线程中的一个,它本身是单线程的。浏览器还包括很多其他线程,如界面渲染线程,浏览器事件触发线程,Http请求线程等。
所谓的javascript是单线程的,是指javascript运行在浏览器中是单线程的,叫做javascript引擎线程。
下面这个例子会让我们差生怀疑,产生一种JS是多线程的错觉:
function fn1(){ setTimeout(function(){ alert("我先调用")},1000);}function fn2(){ alert("我后调用");}fn1();fn2();//先弹出:"我后调用"//1s后弹出:"我先调用"
看上去,fn2()和延时程序是分两个程序走,但其实,这是JS的“回调”机制在起作用,类似于操作系统中的“中断和响应”——延时程序设置一个“中断”,然后执行fn2(),等待1000ms之后,再回调执行函数fn1()。
下面这个例子也是JS回调函数的实例:
<script type="text/javascript"> function fnOnLoad(){ alert("I am outside the Wall!"); } </script> <body onload="fnOnLoad();"> <script type="text/javascript"> alert("I am inside the Wall.."); </script> </body> //先弹出“I am inside the Wall..”; //后弹出“I am outside the Wall!”
body的onload事件调用的函数,也是利用了回调机制——body加载完成之后,回调执行fnOnLoad()函数
- JS脚本解析与执行顺序
- js脚本执行顺序
- HTML中Js脚本的执行顺序
- js加载与执行顺序
- js编译与执行顺序
- JS-1-解析与执行
- NAT与ACL执行顺序解析
- Unity脚本生命周期, Unity脚本函数执行流程与顺序
- js 程序执行与顺序详解
- js 程序执行与顺序实现详解
- js 程序执行与顺序实现详解
- js 程序执行与顺序实现详解
- js 程序执行与顺序实现详解
- js 程序执行与顺序实现详解
- js 程序执行与顺序实现详解
- js代码执行顺序与作用域
- js与jsp的执行顺序
- js 程序执行与顺序实现详解
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job (dfs序树型转线性 线段树区间修改区间查询)
- JSON与GO
- request的一些方法
- Oracle数据库SID显示异常处理
- C语言itoa()函数和atoi()函数详解(整数转字符C实现)
- JS脚本解析与执行顺序
- 利用DBMS_SPACE包对Oracle 表碎片进行监控与清理
- 神经网络 II:神经元模型
- 短科幻连载之《数据将来时》0
- Java异常之checked与unchecked
- PHP生成随机密码的4种方法及性能对比
- Android Studio 插件推荐
- ES6-指令
- (零)博客初衷