JavaScript之执行顺序

时间:2014-04-29 13:43:21   收藏:0   阅读:320

前言

       接触js一段时间以来,觉得只是了解了很浅层的东西。对于很多基础的知识还是很欠缺的。所以开始使用博客来对这一部分的知识做个慢慢的记录和积累。相信积少成多,慢慢的将这一部分的知识攻克!

       第一篇记录的不是相关的应用,而是很底层的知识---JavaScript解析引擎。想要了解这一部分的知识也是通过在项目中遇到的问题而联想到的。

问题的背景

       在一段脚本中,执行的顺序是先将js文件中的alert()执行了一遍,然后当我具体调用到那个函数的时候再执行这个函数。当时看到就产生了一个疑问:执行函数之前为什么执行了alert(),很明显他没有执行我定义的函数,却执行了alert();

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js执行测试</title>
</head>
<script>
	var a ;
	a = 1;
	function f1(){ alert("第一个函数"); }
	alert("测试");
	function f2(){ alert("第二个函数"); }
	alert(a);
	function f3(){ alert("第三个函数"); }
</script>

<body>
	<div>
		<a herf="#" onclick="f1()">测试</a>
	</div>
</body>
</html>

执行结果是:测试   1


需要了解的前提

         需要了解两个概念,一个是JavaScript解析引擎;另外一个是JavaScript解析引擎和浏览器的关系

1.JavaScript解析引擎

  解释执行脚本的程序。可以看成是一个解释器。
  这个引擎需要完成两个功能:
     一是解释脚本程序,将js代码读懂。
     二是执行脚本程序,将脚本程序读懂之后就要执行这个程序。
   比如在一篇博客中看到的一个例子,当你写了 var a = 1 + 1; 这样一段代码,JavaScript引擎做的事情就是看懂(解析)你这段代码,并且将a的值变为2。
     看这个概念的时候还想起另外一个概念就是编译器,它只是将源代码编译成另外一种代码(比如机器码,或者字节码)。就好象是一个翻译官,将中文翻译成英文。它不能够执行这段程序。

2.JavaScript解析引擎和浏览器的关系

        JavaScript解析引擎是浏览器的组成部分之一。
        当了解了前提之后我们知道,我们写的js代码是需要通过浏览器中的JavaScript解析引擎解析执行的,具体的解析机制大家可以google一下,我对这部分了解不深,只知道了解各大概,但是我觉得这些知识对于我了解其他的知识已经足够了。
       解析机制分为两个大过程,一个编译过程,另外一个是执行过程。编译过程最终是在内存中构建一个语法树。执行过程就是按照语法树来执行代码。对于编译和执行内部具体的运行我就不清楚了。

js代码在页面中的执行顺序

      上面讲到的都是一些理论知识,下面就来看看我们在实际应用过程中会js代码在页面中的执行顺序。这些就是上面理论知识的一些很形象的反应。

1. 引擎对js解析---预编译和执行顺序关系

       它会在预编译期对所有声明的变量和函数进行处理。所以,就会出现当JavaScript解释器执行下面脚本时不会报错:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js执行测试</title>
</head>
<script>
	alert(a);   //undefined
	var a ;
	a = 1;
	function f1(){ alert("第一个函数"); }
	alert("测试");  //测试
	function f2(){ alert("第二个函数"); }
	alert(a);  //1
	function f3(){ alert("第三个函数"); }
</script>

<body>
	<div>
		<a herf="#" onclick="f1()">测试</a>
	</div>
</body>
</html>
执行结果是: undefined   测试  1 

       预编译做的工作:将声明的变量和函数做处理,从而使其在执行期间对所有的代码都是可见的。

       但是,你也会看到,执行上面代码,提示的值是 undefined,而不是1。这是因为,变量初始化过程发生在执行期,而不是预编译期。在执行期,JavaScript解释器是按着代码先后顺序进行解 析的,如果在前面代码行中没有为变量赋值,则JavaScript解释器会使用默认值undefined。由于在第二行中为变量a赋值了,所以在第三行代 码中会提示变量a的值为1,而不是undefined。


2. 文件流加载时---js按照HTML文档流顺序执行

      js可以看成HTML文档的组成部分。HTML文档是从上到下逐步解析的。无论是使用<script></script>块还是使用外部引用的js文件都是如此。

使用外部js文件引用,将上面的代码写到js文件中,执行结果不变

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js执行测试</title>
</head>
<script type="text/javascript" src="Untitled-2.js"></script>
<body>
	<div>
		<a herf="#" onclick="f1()">测试</a>
	</div>
</body>
</html>

js文件

var a ;
a = 1;
function f1(){ alert("第一个函数"); }
alert("测试");
function f2(){ alert("第二个函数"); }
alert(a);
function f3(){ alert("第三个函数"); }


执行结果:测试  1  

3. 文件流加载完成之后---按照事件机制改变js执行顺序

类似于调用函数,在哪里调用到就在此处执行,如果没有调用到就不执行。从上面的代码中可以看到,为a标签添加了点击事件,所以当单击的时候会执行对应的函数

总结

所以可以解释为什么alert()执行了,而函数没有执行。js解析引擎要有一个预编译过程,对定义的变量和函数做处理。同时js还要根据HTML文档流的顺序执行。这就是执行我自己定义的函数之前的过程,而我所以的执行自己定义的函数其实是事件机制调用js的一个体现。



评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!