今天在群里看到了一道题,如下。问输出什么?
var c = 1;
function c(c) {
console.log(c);
var c = 2;
}
c(3);
看到的第一眼,第一想法就是这题考察的是变量提升,唔,应该是输出undefined。结果不对,报错了

为啥呢?原来在一个作用域中,变量声明是有顺序的:函数形参声明--->函数声明---->变量声明 。任何一种声明,如果在前面出现,都不会再次声明。所以当变量提升时,也就只有一个有效了。
所以在函数执行环境对应的变量对象中,首先是c:function,然后到第一行定义c=1,所以在变量对象中有变成了c:1,在然后到c(3)语句,此时c定义为了数字,所以报错c is not a function。
同理改变一下上面的代码,在看看它的输出。
var c = 1;
function d(c) {
console.log(c);
var c = 2;
}
d(3);
输出是3,为什么呢?因为在执行d(3)时,函数d的执行环境推入环境栈中,与之关联的变量对象也生成,根据之前的规则,先声明函数参数,所以c:3,后面的var变量声明就无效了。

那什么时候才会出现我刚开始答的输出undefined呢?想下面这样时,他输出就是undefined的。
var c = 1;
function d() {
console.log(c);
var c = 2;
}
d();
因为不存在函数参数声明,也不存在函数声明,所以执行变量声明,于是a先被提升到函数作用域顶端,其变量对象中的值为{a:undefined},所以输出undefined。
不懂的地方还有很多,每次有收获就值得记录一下,不过说的也不一定对,希望能指正出来。
本文探讨了JavaScript中变量提升的规则及作用域中的变量声明顺序,解释了不同情况下函数参数、函数声明与变量声明之间的交互,以及如何影响程序执行结果。
682

被折叠的 条评论
为什么被折叠?



