下面内容参考:http://blog.csdn.net/cxiaokai/article/details/7552653
http://www.jb51.net/article/36755.htm
首先,对于一个html文档,浏览器是按着从上到下逐步解析页面结构和信息的。JavaScript代码作为嵌入的脚本应该也算做HTML文档的组成部分,所以JavaScript代码在装载时的执行顺序也是根据脚本标签<script>的出现顺序来确定的。 而且,不管是在html里面的脚本,还是通过<script src="">这样的引用外面的js文件的脚本,都是按照其原来的顺序来加载的。 不会因为是外部JavaScript文件而延期执行!!
js一个重要的部分就是函数,函数的定义方式大致有两种:
//“定义式”函数定义 function Fn1(){ alert("Hello World!"); } //“赋值式”函数定义 var Fn2 = function(){ alert("Hello wild!"); }
而对于一个js脚本,它的执行其实是分为两个步骤的,先是“预编译”,再是“执行期”.
在预编译的过程中,会把定义式的函数优先执行,也会把所有var变量创建,默认值为undefined,以提高程序的执行效率。
页面加载过程中,浏览器会对页面上或载入的每个js代码块(或文件)进行扫描,如果遇到定义式函数,则进行预处理(类似于C等的编译),处理完成之后再开始由上至下执行;遇到赋值式函数,则只是将函数赋给一个变量,不进行预处理(类似1中变量必须先定义后引用的原则),待调用到的时候才进行处理。(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)
//“定义式”函数定义 Fn1(); function Fn1(){ alert("Hello World!"); }
正常执行,弹出“Hello World!”,浏览器对Fn1进行了预处理,再从Fn1();开始执行。
//“赋值式”函数定义 Fn2(); var Fn2 = function(){ alert("Hello wild!"); }
Firebug报错:Fn2 is not a function,浏览器未对Fn2进行预处理,依序执行,所以报错Fn2未定义。
这是因为,上面示例中定义的函数仅作为值赋值给变量Fn2,所以在预编译期,JavaScript解释器只能够为声明变量f进行处理,而对于变量f的值,只能等到执行期时按顺序进行赋值,自然就会出现语法错误,提示找不到对象f。
3. 代码块及js文件的处理
“代码块”是指一对<script type=”text/网页特效”></script>标签包裹着的js代码,文件就是指文件啦,废话:D
浏览器对每个块或文件进行独立的扫描,然后对全局的代码进行顺序执行(2中讲到了)。所以,在一个块(文件)中,函数可以在调用之后进行“定义式”定义;但在两个块中,定义函数所在的块必须在函数被调用的块之前。
很绕口,看例子好了:
代码如下:
<script type="text/javascript"> Fn(); </script> <script type="text/javascript"> function Fn(){ alert("Hello World!"); } </script>
虽然说,JavaScript是按块执行的,但是不同块都属于同一个全局作用域,也就是说,块之间的变量和函数是可以共享的。
4. 重复定义函数会覆盖前面的定义
这和变量的重复定义是一样的,代码:
代码如下:
function fn(){ alert(1); } function fn(){ alert(2); } fn();
// 弹出:“2”
如果是这样呢:
代码如下:
fn(); function fn(){ alert(1); } function fn(){ alert(2); }
// 还是弹出:“2”
还是弹出“2”,为什么?2都讲了好吧…