了解javascript中函数执行顺序
我个人觉得一般人不会有这种写法,但艺不压身,呵呵。希望能帮到初学的朋友!大家一起进步!
首先列举出8个例子,然后例子的解答会在文章末尾贴出!
测试代码一:
<script language="JavaScript" type="text/javascript"> function myFn(){ alert('Fn1'); }; myFn(); function myFn(){ alert('Fn2'); }; myFn(); </script>
// 两次输出的结果都是Fn2,而不是我们认为的第一次输出Fn1,第二次输出Fn2
测试代码二:
<script type="text/javascript" type="text/javascript"> function myFn(){ alert('Fn1'); }; myFn(); </script>
<script type="text/javascript"> function myFn(){ alert('Fn2'); }; myFn(); </script>
这次第一次输出Fn1,第二次输出Fn2.继续测试,
测试代码三:
<script language="JavaScript" type="text/javascript"> var myFn = function(){alert('Fn1');}; myFn(); myFn = function(){alert('Fn2');}; myFn(); </script>
这次输出的结果是Fn1,Fn2.
测试代码四:
<script language="JavaScript" type="text/javascript"> function myFn(){alert('Fn1');}; myFn(); myFn = function (){alert('Fn2');}; myFn(); </script>
输出Fn1,Fn2.
测试代码五:
<script language="JavaScript" type="text/javascript"> var myFn = function(){alert('Fn1');}; myFn(); function myFn(){alert('Fn2');}; myFn(); </script>
输出Fn1, Fn1
测试代码六:
<script language="JavaScript" type="text/javascript"> myFn(); var myFn = function(){alert('Fn1');}; myFn(); function myFn(){alert('Fn2');}; myFn(); </script>
输出结果是Fn2,Fn1,Fn1
测试代码七:
<script language="JavaScript" type="text/javascript"> myFn(); function myFn(){alert('Fn1');}; </script>
输出Fn1,而不是未定义的函数
测试代码八:
<script language="JavaScript" type="text/javascript"> myFn(); var myFn = function(){alert('Fn1');}; </script>
则提示缺少对象,也就是函数没定义。
测试代码九:
<script language="JavaScript" type="text/javascript"> myFn(); </script> <script type="text/javascript" type="text/javascript"> function myFn(){alert('Fn1');} </script>
则提示缺少对象,也就是函数没定义。
注:这是我引用网络上的部分文章内容 我觉得挺好的,所以就在博客发出来,分享一下!
从上面的例子中,可以发现出一点,就是javascript好像也具有"预编译"(这是我的叫法)的特点,有点类似于传统编译型c或c++等。但是在
javascript中,这种预编译的特性并不是对所有的js代码进行的。大家可以试下把myFn的函数定义分别放到不同的script代码块中进行调用
的时候,会提示对象为定义。所以我个人觉得,js中的这种“预编译”特性值只是针对属于同一个代码块(指的
是<script></script>)内的代码有效。
所以,在javascript的执行过程中,js引擎扫描每一script块的代码,把里面的各种函数定义都抽出来进行“预编译”,注意,这里说的是函数定义而不是函数赋值,或者说是定义式的函数,如下的形式就是"定义式的函数":
function myFn(){
//Something Code
};
编译完成后,就会根据script块中的语句从上到下,从左到右进行执行。然后咱们来分析一下各个测试的结果!
测试代码一:
首
先js引擎扫描该script块中的函数定义(注意这个时候还没开始执行代码),发现有定义式函数function
myFn(){}有两处,由于名字是一样的,编译后就合成了一个myFn函数,后面的定义覆盖了前面的定义,所以在函数执行之前就只有一个编译的函数
myFn,并且其定义是后面的那个,因此真正到执行代码的时候,也就是第一次调用myFn(),输出的当然是Fn2,第二次执行myFn同样输出Fn2.
测试代码二:
由
于javascript的块编译特性,因此分成在不同的块中的代码是分开编译的,所以第一个script块编译后的myFn函数并没有被第二块的myFn
覆盖,因此第一个执行myFn输出的是Fn1,同样第二块输出的是Fn2.需要重点指出的是var myFn =
function(){};不是定义式函数声明,而是赋值语句,把一个函数对象赋值给一个变量,赋值语句的执行时机晚于编译期,定义式函数是在执行语句之
前就已经完成了,而赋值语句要到执行的时候才进行。所以结果就如同大家看到的一般!
根据这样的分析,我想大家也应该能够看出后面例子的输出结果了!