见如下两个练习题比较:
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
?究竟这个函数体内的全局变量影响和改变了什么?或者是我个人对声明提前和作用域不理解在哪里?
请大神指点,小白,感激不尽。
这是第一个的实际执行顺序。你可以看到只有变量的声明被提前了,赋值还在原位置。
至于为什么输出的a是undefined,因为作用域的关系,在函数作用域内有需要的变量,则会去读取此作用域内的变量的值,读取的时候作用域内的a是undedined,尚未进行a=100,所以就是undefined。而作用域内无此变量的声明时才会去上一层外部作用域找值。需要注意的是有形参话,也属于发生了声明。
手机不方便贴链接,你可以去链接这个问题或搜其他相关的问题,解释的都比较好。