JavaScript中var声明的局部变量为何会覆盖全局变量?
为什么嵌套if里的var x会修改全局变量?
嘿,你这个问题刚好戳中了JavaScript里var关键字最容易混淆的点——函数作用域 vs 块级作用域,我给你一步步掰扯明白:
首先先把你的代码贴出来方便分析:
var x = 3; if(1==1){ if(2==2){ var x= 5; } } document.write(x); // outputs 5
核心原因:var是函数作用域,不认代码块
你之前的认知误区在于,以为if这类代码块会创建局部作用域,但这是let/const的特性,var完全不买账!
用var声明的变量,作用域只限于当前函数内部,如果不在任何函数里,那就是全局作用域。不管你把var x = 5嵌套多少层if、for块,只要不在函数里,这个x和最开头声明的x就是同一个全局变量。
再深入点:变量提升(Hoisting)在搞鬼
JavaScript在执行代码前,会先扫描整个作用域,把所有var声明的变量“提升”到作用域的最顶部。所以你的代码其实等价于下面这样:
var x; // 变量声明被提升到全局作用域顶部 x = 3; // 赋值留在原地 if(1==1){ if(2==2){ x= 5; // 这里根本不是重新声明变量,只是给已经存在的全局x赋值! } } document.write(x); // outputs 5
对比一下块级作用域的正确用法
如果想要内层变量不影响外层,换成let就可以了——let是块级作用域,会被if这类代码块隔离:
let x = 3; if(1==1){ if(2==2){ let x= 5; // 这是if块内的局部变量,和外层x无关 } } document.write(x); // outputs 3
总结一下
var的作用域是函数级/全局级,不被if/for等代码块限制;let/const才是块级作用域,会被代码块隔离;- 变量提升让
var声明的变量在整个作用域内都可访问,内层的赋值本质是修改同一个变量。
内容的提问来源于stack exchange,提问作者aziz
相关产品推荐
相关产品推荐

