JavaScript变量提升疑问:函数内var变量为何输出undefined?
为什么会得到undefined?
1. 函数内部用var的情况
先看这段代码:
var numOfBeers = 5; function getMoreBeers() { console.log('I have this many beers: ' + numOfBeers); // undefined var numOfBeers = 25; return numOfBeers; } console.log('I now have this many beers: ' + getMoreBeers());
运行结果:
I have this many beers: undefined I now have this many beers: 25
核心原因是函数作用域里的var声明会被提升到作用域顶部,但赋值操作留在原地。
JavaScript执行函数代码前,会先扫描整个函数作用域,把所有var声明的变量“提前”到作用域最开头,但赋值语句还是留在原来的位置。上面的函数代码相当于被拆解成了这样:
function getMoreBeers() { var numOfBeers; // 声明被提升,变量默认值为undefined console.log('I have this many beers: ' + numOfBeers); // 输出undefined numOfBeers = 25; // 执行赋值 return numOfBeers; }
另外,函数内部的var变量会遮蔽全局的同名变量,所以这里的numOfBeers和外面的var numOfBeers = 5没有关联,不会读取全局的那个值。
2. 全局作用域用var的情况
再看这段代码:
console.log('I have this many beers: ' + numOfBeers); var numOfBeers = 25;
你得到的运行结果是I have this many beers: 25,这是特殊场景导致的——大概率是你之前在控制台已经声明过numOfBeers变量(比如运行了第一个代码里的全局var)。
如果是在全新的控制台环境运行这段代码,正常结果应该是undefined,因为全局作用域的var同样会提升,代码实际执行顺序相当于:
var numOfBeers; // 声明提升 console.log('I have this many beers: ' + numOfBeers); // 输出undefined numOfBeers = 25; // 执行赋值
3. 用let的情况
最后这段代码:
console.log('I have this many beers: ' + numOfBeers); let numOfBeers = 25;
运行报错Uncaught SyntaxError: Identifier 'numOfBeers' has already been declared,原因有两点:
let不允许在同一作用域下重复声明同名变量,你之前已经用var在全局声明过numOfBeers,所以再用let声明直接触发语法错误。- 就算是在全新环境运行这段代码,也会报
ReferenceError:let的变量会被提升,但会进入暂时性死区,在声明语句之前访问变量会直接报错,而不是返回undefined。
内容的提问来源于stack exchange,提问作者zi zi
相关产品推荐
相关产品推荐

