不同作用域下let、const、var在变量遮蔽/重声明时的差异是什么
var、let、const声明差异原因说明
核心的行为差异来源于三种声明关键字的作用域规则和重复声明限制不同:
var属于函数作用域,允许同一作用域下重复声明,声明会自动提升到当前函数作用域顶部let/const属于块级作用域,严格禁止同一作用域下重复声明,只要当前作用域已经存在同名变量(不管是用var还是let/const声明的),重复声明就会触发语法错误
第一段代码(var重声明无报错)执行逻辑
var a=12; //Global variable foo(); //hoisting function foo() { console.log("a="+a); var a=13; console.log("a="+a); if(true) { const a=89; console.log("in block="+ a); } var a=90; //no error console.log("a="+a); }
- foo函数执行前,内部的
var a声明会被提升到函数作用域顶部,初始值为undefined,所以第一个console.log会输出a=undefined - 第二次
var a=90和第一次的var a=13在同一个函数作用域内,var允许重复声明,这行代码实际等价于给已存在的变量a重新赋值为90,不会触发错误 - if块内的
const a=89属于独立的块级作用域,是合法的变量遮蔽,和外层函数作用域的a互不影响,不存在冲突
第二段代码(let重声明报错)执行逻辑
var a=12; //Global variable foo(); //hoisting function foo() { console.log("a="+a); var a=13; console.log("a="+a); if(true) { const a=89; console.log("in block="+ a); } let a=90; //Or const a :: error console.log("a="+a); }
- 函数作用域内已经通过
var a=13声明了同名变量a - 后续的
let a=90和前面的var a属于同一个foo函数作用域,let的语法规则禁止同一作用域下重复声明同名变量,JS引擎在预编译阶段就会直接检测到这个冲突,抛出「a has already been declared」的语法错误,不需要等到代码执行到对应行
内容的提问来源于stack exchange,提问作者Burak Fıçıcı
相关产品推荐
相关产品推荐

