函数的执行顺序
首先确定一点,函数有两种定义方式:
1 声明式函数
function func(){
// code here
}
2 赋值式函数
var func = function(){
// code here
}
二者的区别在于,声明式函数会在JS的预编译期被先提取出来,然后才按顺序执行JS代码。
(计算机在开始执行语句之前,会先查找所有的function定义,然后保存相关的function。)
变量提前
JS中会将一个作用与内的函数变量的声明提前到当前作用域的最开始,表明这个变量在这个作用域的存在,然后再按顺序执行,执行到赋值语句时进行赋值。
var i=10;
function a() {
alert(i);
var i = 2;
};
a();
所以上述例子的结果是undefined,因为上面的代码也相当于:
var i=10;
function a() {
var i;
alert(i);
i = 2;
};
a();
在函数作用于内定义了i,但是执行alert时并没有赋值,所以是undefined。
赋值式函数也按照这样的顺序去执行。
但是声明式函数会被提前在JS预编译阶段被解析,也就相当于声明与赋值(函数定义)同时在最开始阶段执行了。
所以对于声明式函数:
func(5);
function func(i){
console.log(i)
}
相当于:
function func(i){
console.log(i)
}
func(5);
所以结果是5
但是对于赋值式函数就不同了:
func(5);
var func = function(i){
console.log(i)
}
结果报错,“func is not a function”,原因是上面的代码相当于:
var func;
func(5);
func = function(i){
console.log(i)
}
变量声明提前,但是赋值(也就是定义函数)在后,所以在执行func(5)时,func根本就是undefined
说明
事实上,JS的解析过程分为两个阶段:预编译期(预处理)与执行期。
预编译期JS会对本代码块中的所有var声明的变量和函数进行处理(类似与C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。
执行期 会按照代码块的顺序逐行执行。
建议
- 函数体内变量最好var声明为局部,保持安全性和局部性。
- 所有变量的声明最好一次性写在作用域的顶端,函数不必需如此
- 函数的执行方法 最好在 函数的定义之后