try块中的JavaScript范围

时间:2012-05-04 02:00:18

标签: javascript scope

说我正在尝试执行此JavaScript代码段。假设未声明的变量和方法在上面的其他地方声明,并且somethingsomethingElse计算为boolean-true。

try {
    if(something) {
        var magicVar = -1;
    }

    if(somethingElse) {
        magicFunction(magicVar);
    }
} catch(e) {
    doSomethingWithError(e);
}

我的问题是:magicVar的范围是什么,是否可以像我一样将其传递给magicFunction

6 个答案:

答案 0 :(得分:30)

关于Javascript如何使用var处理此问题的许多其他好答案,但我认为我会解决let情况......

如果在let块中使用try定义变量,则它不在catch(或finally)块内的范围内。它需要在封闭块中定义。

例如,在以下代码块中,控制台输出将为“Outside”:

let xyz = "Outside";

try {
    let xyz = "Inside";

    throw new Error("Blah");
} catch (err) {
    console.log(xyz);
}

答案 1 :(得分:21)

Javascript具有功能范围。这意味着magicvar将从它声明的函数的开头一直存在到该函数的结尾,即使该语句没有执行。这称为变量提升。函数声明也会发生同样的事情,而声明又称为函数提升

如果变量是在全局范围内声明的,那么所有内容都可以看到它。这是全局变量在Javascript中被认为是邪恶的部分原因。

如果undefined为false,您的示例会将magicFunction传递给something,因为magicVar尚未分配给任何内容。

虽然这是技术上有效的Javascript,但它通常被认为是不好的风格,并且不会传递像jsLint这样的样式检查器。非常不直观的Javascript会执行而不会出现任何错误

alert(a); //alerts "undefined"
var a;

POP QUIZ :以下代码有什么作用?

(function() {
  x = 2;
  var x;
  alert(x);
})();
alert(x);

答案 2 :(得分:5)

  • 在javascript中,只有函数创建一个新的context -closure。
  • 变量的每个定义实际上都是其范围顶部的变量声明,以及定义所在位置的赋值。

<强> VAR

  • 函数作用域
  • 提升到其功能的顶部
  • 同一范围内同名的重新声明是no-ops

您可能需要阅读MDN scope cheat sheet

由于hoisting你甚至可以这样做:

function bar() {
    var x = "outer";

    function foo() {
        alert(x); // {undefined} Doesn't refer to the outerscope x
        // Due the the var hoising next:        
        x = 'inner';
        var x;
        alert(x); // inner

    }
    foo();
}

bar();​

bar();​

Demo

所以foo函数转换为这样的东西:

function foo() {
    var x;
    alert(x); // {undefined} Doesn't refer to the outerscope x
    // Due the the var hoising next:        
    x = 'inner';
    alert(x); // inner
}​
  

我的问题是:magicVar的范围是什么,可以像我一样将它传递给magicFunction吗?

定义好的 ...,是的,代码是有效的,但如果变量声明位于顶部,那么它的可读性就会降低,这就是全部。

答案 3 :(得分:3)

由于javascript“hoisting”(google it),您的变量声明代码会被翻译为:

function yourFunction() {
  var magicVar;
  try {
      if(something) {
          magicVar = -1;
      }

      if(somethingElse) {
          magicFunction(magicVar);
      }
  } catch(e) {
      doSomethingWithError(e);
  }

} //end of your function

“Hoisting”将所有变量声明移动到函数的顶部。因此magicVar在函数的任何地方都可用,但在给它一个值之前它是未定义的。

您的变量具有功能范围。

答案 4 :(得分:1)

对于var,变量从函数的开头到它的结尾都存在,无论它们在何处被声明,或者即使实际上已经到达了该语句。但是,它们将undefined,直到它们被赋予另一个值。

因此,在您的情况下,如果something为false但somethingelse为真,您将调用magicFunction,其第一个参数为undefined

{J} 1.9中创建的let关键字(截至今天,5月3日 rd 2012,据我所知)仅在Firefox中,使用作用域声明变量您可能习惯的语义。

答案 5 :(得分:0)

我同意变量提升和功能提升,我想强调两个导入点。

  • Catch参数中定义的标识符即err / e(错误),其范围限定为Catch defined block。

  • 功能首次提升。 例如:

    await Navigation.PopAsync();