【问题标题】:No hoisting in catch statement?在 catch 语句中没有提升?
【发布时间】:2019-03-28 16:20:13
【问题描述】:

我有这个代码:

(function() {
   var ex;
   try {
       throw new Error('blah');
   } catch(ex) {
       console.log('ex i here:', ex);
   }
   console.log('ex out here:', ex);

   return 'hi';
})()

此日志:

ex i here: Error('blah');

在这里:未定义

为什么会这样?我认为由于提升,ex 会被设置在这个块范围之外,所以它应该在ex out here 中可用。

我希望它的工作方式类似于 for 循环:

for (i=0; i<2; i++) {
}
console.log(i); // gives 2

【问题讨论】:

  • catch(ex) ex 适合你。
  • ex in catch 不是声明的 var,它是一个参数,它实际上会影响您的 ex var
  • @KirkLarkin 我不这么认为......这与异常“参数变量”无关
  • @Noitidart 阴影意味着参数是与外部范围不同的变量。即使它们具有相同的名称,但参数是不同的,并且您不再可以从外部范围访问同名的变量。在您的示例中,名为 ex 的两个变量是两个不同的变量——一个在外部范围内,一个是参数。

标签: javascript hoisting


【解决方案1】:

你搞砸了一些事情。

定义为var 的变量具有函数作用域。 catch 中的参数没有被提升,它具有块范围(仅在那个捕获部分)。

正如您在此示例中看到的:ab 被提升,然后可以在 catch 部分之外访问。 ex2 在上下文之外不存在。

(function() {
   var ex;
   try {
       throw new Error('blah');
   } catch(ex2) {
       var ab = 3;
       console.log('ex is here:', ex2.message);
   }
   console.log(ab);
   console.log(ex2);
   console.log('ex out here:', ex);

   return 'hi';
})()

在您的示例中,创建了具有相同名称但范围不同的不同变量。如果发生这种情况,那么(几乎在所有语言中)都会使用上下文中的“最深”变量。 如果您想通过托管将错误排除在 catch 之外,您可以:

(function() {
   try {
       throw new Error('blah');
   } catch(ex2) {
       var ex = ex2;
       console.log('ex is here:', ex2.message);           
   }
   console.log(ex.message);

   return 'hi';
})()

【讨论】:

  • 这太棒了,谢谢。我试图让变量在范围之外可用。并且很困惑为什么没有发生吊装。
【解决方案2】:

这段代码的行为是这样的

  (function() {
   var ex1;
   try {
       throw new Error('blah');
   } catch(ex2) {
       console.log('ex i here:', ex2);
   }
   console.log('ex out here:', ex1);

   return 'hi';
  })()

这是因为在 catch 中声明的第二个 ex 仅在 catch 的范围内可见,更多信息visit


关于循环,在这些迭代中,js 查找包含它的最近范围的变量“i”声明,在这种情况下,它是父级,因此正在更改的变量“i”是在开始,因为在 de 循环中没有变量声明。

【讨论】:

    【解决方案3】:

    来自try ... catch statement

    try 块中抛出异常时,exception_var(例如,catch (e) 中的e)保持throw 语句指定的值。您可以使用此标识符来获取有关所引发异常的信息。此标识符是 catch 子句的本地标识符。即在进入catch子句时创建,在catch子句执行完毕后,标识符不再可用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-06
      • 2021-01-04
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      相关资源
      最近更新 更多