Function专题 以及js的预解析理解

提问:函数可以先调用再定义吗?

回答:可以。使用“函数语句”的方式定义的函数可以“先使用,后定义”。而使用“表达式”定义的函数只能“先定义,后使用”。

在JS中,定义函数有两种方式,分别是“函数语句”和“表达式”。

函数语句写法:

1 function关键字   函数名(参数列表...){
2 
3   函数功能代码
4  }
5   function apple(){
6     console.log('apple');
7   }

 函数表达式写法:

1 var orange = function(){
2      console.log(orange );
3 };

 下面使用了两种方式声明了两个函数,分别在不同的地方调用两个函数

 1 apple();
 2 function apple(){
 3     console.log("apple");
 4 }
 5 
 6 var orange = function(){
 7     console.log("orange");
 8 }
 9 orange();
10 
11 mango();
12 var mango = function(){
13     console.log("mango");
14 }

执行结果:

所以得到结论:使用“函数语句”的方式定义的函数可以“先使用,后定义”。而使用“表达式”定义的函数只能“先定义,后使用”。

javascript 代码运行分两个阶段

1、预解析 --- 把所有的变量声明提前,所有的函数定义提前,变量的赋值不提前。
2、执行 --- 从上到下执行 (setTimeout,setInterval,ajax中的回调函数,事件中的函数例外需要触发执行)。

需要注意的点:

1、JavaScript解析器并非一行一行地分析和执行程序,而是一段一段地进行预编译后然后再执行的。

1 function fruit(){
2         alert("apple");
3 }
4 fruit(); //这里调用fruit,输出orange而不是apple
5 function fruit(){
6     alert("orange");
7 }
8 fruit(); //这里调用fruit,当然输出orange

两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,可以这么写。不过,程序运行之后却发现一个奇怪的现象:两次调用都只是最后那个函数里输出的值!显然第一个函数没有起到任何作用。这是为什么呢?


原来,JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地进行预编译后然后再执行的。而且,在同一段程序中,函数 在被执行之前 会被预定义,后定定义的 同名函数 会覆盖 先定义的函数。在调用函数的时候,只会调用后一个预定义的函数(因为后一个预定义的函数把前一个预定义的函数覆盖了)。也就是说,在第一次调用fruit之前,第一个函数语句定义的代码逻辑,已被第二个函数定义语句覆盖了。所以,两次都调用都是执行最后一个函数逻辑了。

 1 <script>
 2     function fruit(){
 3         alert("apple");
 4     }
 5     fruit(); //这里调用fruit,输出apple
 6 </script>
 7 <script>
 8     function fruit(){
 9         alert("orange");
10     }
11     fruit(); //这里调用fruit,输出orange
12 </script>

这时,输出才是各自按顺序来的,也证明了JavaScript的确是一段段地进行预编译后然后再执行的。

2、JS解析器先预声明变量(预定义变量只是声明了一下变量,而并没有对其赋值。),再预定义函数 。

1 alert(addB); 
2 var addB = "variable";
3 //结果 undefined  JS解析器会先预定义 addB 变量为 undefined,但没有赋值
4 
5 var addB = "variable";
6 alert(addB); 
7 //结果 variable JS解析器会先预定义 addB 变量为 undefined,然后 addB 被赋值为 "variable",因此最后执行结果是 "variable"

说明了预定义变量只是声明了一下变量,而并没有对其赋值

1 alert(addB);  //结果  function addB(){alert("function addB")}
2 var addB = "variable"; 
3 function addB() { 
4     alert("function addB"); 
5 } 
6 alert(addB);  //结果 variable

JS解析器先预定义了 addB 变量为 undefined, 但是 addB 函数覆盖了此变量,因此一开始执行结果是 function...,然后 addB 被赋值为 "variable",因此最后执行结果是 "variable"

原文地址:https://www.cnblogs.com/sanerandm/p/8338450.html