首先看一段JS代码,其中使用了两种方式声明了两个函数,分别在不同的地方调用两个函数:
<script>
'use strict';
// 输出hello函数
console.log(hello);
// 定义hello函数
function hello(){
alert("Hello");
}
// 输出hi变量
console.log(hi);
// 给hi赋一个函数
var hi = function(){
alert("Hi");
}
// 输出变量hi
console.log(hi);
</script>
在JS中,定义函数有两种方式,分别是“函数语句”和“表达式”。
- 针对hello函数,我在还没有定义它之前就调用了它,并且我定义hello函数使用的“函数语句”定义的方式。
- 针对hi函数,我使用的是“表达式”的定义方式,也在定义之前和之后调用了该函数。
结果如下所示:
我们可以看到,使用“函数语句”的方式定义的函数可以“先使用,后定义”。而使用“表达式”定义的函数只能“先定义,后使用”。
为什么会出现这种情况呢,我谈谈我个人的理解,如果有不对的地方,希望可以帮我纠正一下:
我们都知道JS默认有一个全局对象window,在运行一段JS代码时:
第一步:JS引擎会先扫描整个JS代码,把所有全局变量都绑定到window对象上,包括hello和hi这两个变量。此时,window上就有了hello函数(包括函数体)和hi变量(但值为undefined)。
第二步:开始从第一行执行JS代码,这时虽然还没有执行到hello函数的定义语句,但是window中已经有了函数定义了。而没有执行到hi变量的赋值语句之前,hi变量用于是undefined。
综上所述:导致了两种函数定义方式导致的“定义”和“使用”的顺序不同。
为了验证猜想,我们在JS代码块的开头添加两行console:
console.log(window.hello);
console.log(window.hi);
输出结果如下:
这其中也牵涉到了“变量提升”的概念,其实都可以用绑定到window对象上来理解:在执行JS代码之前,所有的全局变量(包括函数和变量),都会绑定到window对象上,只是函数会包含函数体,变量仅仅是一个undefined。
我只是个新手,如果有理解上的偏差还望指出,万分感谢!