羽翼飞扬

古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。

导航

了解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(){};不是定义式函数声明,而是赋值语句,把一个函数对象赋值给一个变量,赋值语句的执行时机晚于编译期,定义式函数是在执行语句之 前就已经完成了,而赋值语句要到执行的时候才进行。所以结果就如同大家看到的一般!

根据这样的分析,我想大家也应该能够看出后面例子的输出结果了!

posted on 2014-02-08 16:22  羽翼飞扬  阅读(7140)  评论(1编辑  收藏  举报