为何try-catch外的x为undefined而y为10?JS代码疑问
try-catch块中变量作用域问题解析
示例1:同名变量的异常输出
try { throw new Error(); } catch (x) { var x = 100, y = 10; console.log(x); console.log(y); } console.log(x); console.log(y);
输出结果:
100 10 undefined 10
示例2:修改参数名后的正常输出
try { throw new Error(); } catch (x) { var foo = 100, y = 10; console.log(foo); console.log(y); } console.log(foo); console.log(y);
输出结果:
100 10 100 10
问题解析
核心原因在于catch参数的作用域绑定规则,再结合var的变量提升特性:
1. var的变量提升特性
用var声明的变量会被提升到所在全局/函数作用域的顶部,但赋值操作不会提升。也就是说,不管var写在代码的哪个位置,作用域内都会先存在这个变量的声明,初始值为undefined,直到执行到赋值语句才会更新变量值。
2. catch参数的作用域特殊性
catch的参数(比如示例1里的x)会在catch块的局部作用域中创建一个专属变量绑定,这个绑定的优先级高于外部作用域的同名变量,同时会覆盖内部var声明的同名变量。
示例1的执行细节:
- 全局作用域先完成
var x和var y的提升,此时全局的x和y初始值都是undefined。 - 进入catch块后,catch参数
x成为当前局部作用域的变量,此时内部的var x = 100中,var声明会被忽略(因为局部作用域已经有x的绑定),直接将100赋值给局部的x,所以块内console.log(x)输出100。 - 局部作用域中对
y赋值10,这个操作会同步更新全局作用域中已声明的y,所以块内console.log(y)输出10。 - 跳出catch块后,局部的
x被销毁,访问全局的x时,它自始至终没有被赋值过,所以输出undefined;而全局的y已经被赋值为10,因此输出10。
示例2的差异:
内部声明的foo和catch参数x不同名,var foo提升到全局后,在catch块中被赋值100,所以外部访问foo时能拿到100;y的逻辑和示例1一致,外部输出10。
内容的提问来源于stack exchange,提问作者Harsh Mohan Agarwal
相关产品推荐
相关产品推荐

