前端人在面试时经常会遇到有关于js运行顺序的问题。当然经常有很多人答不上来下面来总结一下js的执行顺序。
一、函数执行顺序
1、正常顺序
functionf(){
alert(2);
}4
f();
//alert2
所有浏览器都能测试通过。
2、倒序调用
f();
//alert2
functionf(){
alert(2);
}
之前一些浏览器会报undefined,不过,目前的版本大多都可以了
3、含参函数倒序
f(2);
//alert22
functionf(a){
alert(a);
}
4、声明式函数和赋值式函数
f();//2
functionf(){
//声明式函数
console.log(2);
}
f1();
//UncaughtTypeError:f1isnotafunction
varf1=function(){//赋值式函数
console.log(2);
}
声明式函数与赋值式函数的区别在于:在JS的预编译期,声明式函数将会先被提取出来,然后才按顺序执行js代码。
二、变量执行顺序
1、正常顺序
vara=2;
alert(a);//alert2
2、倒序使用变量
alert(a);//alertundefined
vara=2;
在变量未定义之前使用,会返回undefined。
3、局部变量的执行
*注意:js中全局var声明的为全局变量函数体内var声明为局部变量(函数外部访问不到)但是,函数体内未用var声明的为全局变量(函数外部可以使用)
functionf(){
alert(a);
a=3;
}
f();//error:aisnotdefined
这里Firefox的控制台中会报错ReferenceError(引用错误):a未被定义。。。。所以建议函数体内最好用var声明变量,保持局部性如:
functionf(){
alert(a);
vara=3;
}
f();//undefined
这里alert语句可以弹出,虽然是undefined,但是没有报错,这是为什么呢??
事实上,JS的解析过程分为两个阶段:预编译期(预处理)与执行期。
预编译期JS会对本代码块中的所有var声明的变量和函数进行处理(类似与C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。
执行期会按照代码块的顺序逐行执行。。
*函数内部再次声明赋值,函数f()内有局部变量a时,会优先使用自己的变量,只不过第一次alert时未赋值
vara=1;
functionf(){
alert(a);
vara=3;
alert(a);
}
f();//undefined和3
*函数内部再次全局声明,会修改全局的a
vara=1;
functionf(){
alert(a);
a=2;
alert(a);
}
f();//1和2
*函数内全局赋值一次,var声明一次函数f()内还是会优先使用自己的变量a
vara=1;//函数f()内变量a的执行顺序
functionf(){
alert(a);
a=2;//#2
alert(a);
vara=3;//等价于vara;#1
//a=3;#3
alert(a);
}
f();//undefined2和3
alert(a);//1
函数f()内变量a声明与赋值的执行顺序如上,应该很明确了!!
*一个经典的例子复习一下:
vara,b;
(function(){
alert(a);//undefined
alert(b);//undefined
vara=b=3;//等价于vara=3;b=3;b是全局的
alert(a);//3
alert(b);//3
})();
alert(a);//undefined
alert(b);//3
三、总结
1、JS的解析过程分为两个阶段:预编译期(预处理)与执行期。
预编译期JS会对本代码块(两个script块互不影响)中的所有var声明的变量和函数进行处理(类似与C语言的编译)
此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。
执行期会按照代码块的顺序筑行执行
2、把执行方法写在函数定义之前是不太规范的,但这个界限被弱化了。如今在一个作用范围之内,都可以被正常调用。
所以,建议和优化如下:
1.函数体内变量最好var声明为局部,保持安全性和局部性。
2.所有变量的声明最好一次性写在作用域的顶端,函数不必需如此,如:
functionf(){
vara,b,c;
a=abc;
b=[1,3,1];
c=12;
}
3.函数的执行方法最好在函数的定义之后
全新超实用性的Python零基础入门到就业体验课+视频+源码淘宝¥2购买已下架