简单说明一下JS中的函数声明存在的“先使用,后定义”
首先看一段JS代码,其中使用了两种方式声明了两个函数,分别在不同的地方调用两个函数:
1 <script> 2 'use strict'; 3 // 输出hello函数 4 console.log(hello); 5 // 定义hello函数 6 function hello(){ 7 alert("Hello"); 8 } 9 // 输出hi变量 10 console.log(hi); 11 // 给hi赋一个函数 12 var hi = function(){ 13 alert("Hi"); 14 } 15 // 输出变量hi 16 console.log(hi); 17 </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:
1 console.log(window.hello); 2 console.log(window.hi);
输出结果如下:
这其中也牵涉到了“变量提升”的概念,其实都可以用绑定到window对象上来理解:在执行JS代码之前,所有的全局变量(包括函数和变量),都会绑定到window对象上,只是函数会包含函数体,变量仅仅是一个undefined。
我只是个新手,如果有理解上的偏差还望指出,万分感谢!