简单说明一下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。

我只是个新手,如果有理解上的偏差还望指出,万分感谢!

posted @ 2016-10-27 10:59  雨帘轻挂  阅读(10424)  评论(1编辑  收藏  举报