函数声明提前的问题

见如下两个练习题比较:
1:

var  a=10;
Function  fun(){
    console.log(a);//undefined
    var   a=100;
    console.log(a);//100
}
fun();
console.log(a);//10

2:

var  a=10;
Function  fun(){
    console.log(a);//10
      a=100;
    console.log(a);//100
}
fun();
console.log(a);//100

问题特点:

两题区别在于问题2中在函数中声明的变量为全局变量。

个人疑惑:
我的理解是虽然function声明的函数整体会提前,同时var a也会被提前,但是浏览器在执行时难道不是先读取到var a = 10;吗?然后再读取fun();此时相当于浏览器已经记住了a = 10,因为a是全局变量,因此在执行问题1中的函数内第一个console.log(a)时输出10!但结果输出undefined

个人疑惑:该怎么样理解声明提前?怎样理解提前到自身所在的作用域的顶端?作用域怎么在大脑中抽相出来理解?

问题2中个人疑惑:

如果说将整个函数和变量名a提前到作用域的顶端,对比问题1中第一个结果是undefined,可否理解为此时浏览器并没有读取到a = 10?如果以这个思路理解,虽然在问题2中函数体内声明了全局变量,根据声明提前时,赋值留在原地的原则,第一个console.log(a)为何不是undefined?究竟这个函数体内的全局变量影响和改变了什么?或者是我个人对声明提前和作用域不理解在哪里?

请大神指点,小白,感激不尽。

阅读 3.7k
1 个回答
var a;
Function fun(){
var a;//a=undefined
console.log(a);//undefined
a=100;
console.log(a);//100
}
a=10;
fun();
console.log(a);//10

这是第一个的实际执行顺序。你可以看到只有变量的声明被提前了,赋值还在原位置。
至于为什么输出的a是undefined,因为作用域的关系,在函数作用域内有需要的变量,则会去读取此作用域内的变量的值,读取的时候作用域内的a是undedined,尚未进行a=100,所以就是undefined。而作用域内无此变量的声明时才会去上一层外部作用域找值。需要注意的是有形参话,也属于发生了声明。

手机不方便贴链接,你可以去链接这个问题或搜其他相关的问题,解释的都比较好。

宣传栏