函数的执行顺序(声明式函数、赋值型函数、匿名函数、自执行函数)
声明式函数和赋值型函数的区别在于:在js的预编译期间,声明式函数会被提前提取出来,然后才会按照顺序执行JS代码
//函数声明
a();//a
function a() {
console.log("a");
}
//函数赋值
b();//Uncaught TypeError: b is not a function
var b = function() {
console.log("b");
}
// 匿名函数
function() {}
// 函数使用IIFE自执行
(function () {
console.log("C") //C
})()
JS的解析分为两个阶段:预编译 和 执行期
· 预编译期间:对当前js文件中的所有 声明变量 和 函数进行处理,但是需要注意:1 ,此时处理的只是声明式函数,2,变量也只是进行了声明但是没有进行初始化和赋值。
接下来,我们结合上面分析的来进行示例
f();//输出函数声明2
function f(){
console.log("输出函数声明1")
}
function f(){
console.log("输出函数声明2")
}
结论1 :都是函数声明的情况下,后面的函数会层叠前面的函数
f();//输出函数声明
function f() {
console.log("输出函数声明")
}
var f = function() {
console.log("输出函数表达式")
}
结论2:声明函数提前于赋值函数(函数表达式)
console.log(a);// undefined
var a;
console.log(b);//Uncaught ReferenceError: b is not defined
结论3:变量声明处于预编译阶段。证明了我们上面的所说的都是对的
<script>
f();
</script>
<script>
function f(){};
</script>
结论4:js引擎是按照代码块的顺序来执行的。对于还没有加载的代码,是没有办法进行处理的。这也是编译核心所在
console.log(f); // Function
function f() {
console.log(1);
}
var f = 3;
结论5:函数声明提升优先级大于变量的声明,会优先把标识符给函数使用
<script>
console.log(a);
</script>
<script>
console.log(3);
</script>
结论6:代码块之间如果报错,其他的模块如果正确依旧可以正确执行
总结和整理
JS的执行顺序如下:
- 1.读入第一个代码块
- 2.做语法分析,有错则报语法错误,并跳转到 5
- 3.对var变量和function做 预编译(永远不会报错,因为只解析正确的)
- 4.执行代码块,有错则报错
- 5.如果还有下一个代码块,则读入下一个代码端,重复 2
- 6.结束
ES之前,JS没有变量作用域。只有 函数作用域 和 全局作用域。
{ var a = 3; }
console.log(a); // 3
使用了ES6的let之后,{ }内即为一个变量作用域
{
let a = 3;
}
console.log(a); // error
实战!
代码一:
f();
var scope = 'out';
function f() {
console.log(scope);
var scope = 'in';
console.log(scope);
}
- 变量覆盖,后面定义声明的会覆盖前面的。
- 函数内部:先进行变量声明。
实际运行过程:
var scope = 'out';
function f() {
var scope; // 覆盖了外部的。
console.log(scope);
scope = 'in';
console.log(scope);
}
f();
代码二:
var getName = function(){
console.log(2);
}
function getName (){
console.log(1);
}
getName();
这题看懂了前面的话很容易:
- 函数声明被放在了预编译阶段。
- 后来的会覆盖前面的。
实际运行过程
function getName (){
console.log(1);
}
var getName = function(){
console.log(2);
}
getName(); // 2
代码三:
getName(); // 1
function getName() {
console.log(1);
}
var getName = function() {
console.log(2);
}
依旧很容易,不解释。变量赋值来得太慢,不像龙卷风。