try 块中的 JavaScript 作用域

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10441717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 09:54:14  来源:igfitidea点击:

JavaScript scope in a try block

javascriptscope

提问by user5243421

Say I'm trying to execute this JavaScript snippet. Assume the undeclared vars and methods are declared elsewhere, above, and that somethingand somethingElseevaluate to boolean-true.

假设我正在尝试执行此 JavaScript 代码段。假设未声明的变量和方法在上面的其他地方声明,something并且somethingElse评估为布尔值真。

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

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

My question is: what is the scope of magicVarand is it okay to pass it into magicFunctionas I've done?

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

采纳答案by Peter Olson

Javascript has function scope. That means that magicvarwill exist from the beginning of the function it's declared in all the way to the end of that function, even if that statement doesn't ever execute. This is called variable hoisting. The same thing happens with functions declarations, which in turn is called function hoisting.

Javascript 有函数作用域。这意味着magicvar从它声明的函数的开头一直到该函数的结尾都将存在,即使该语句从未执行过。这称为变量提升。函数声明也会发生同样的事情,这又被称为函数提升

If the variable is declared in global scope, it will be visible to everything. This is part of the reason why global variables are considered evil in Javascript.

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

Your example will pass undefinedinto magicFunctionif somethingis false, because magicVarhasn't been assigned to anything.

你的榜样将传递undefinedmagicFunction,如果something是假的,因为magicVar没有被分配到任何东西。

While this is technically valid Javascript, it's generally considered bad style and will not pass style checkers like jsLint. Extremely unintuitive Javascript like this will execute without any error

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

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

POP QUIZ: What does the following code do?

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

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

回答by DrEnter

Lots of other good answers about how Javascript handles this with var, but I thought I'd address the letsituation...

关于 Javascript 如何使用 处理这个问题的许多其他很好的答案var,但我想我会解决这种let情况......

If a variable is defined with letinside the tryblock, it will NOT be in scope inside the catch(or finally) block(s). It would need to be defined in the enclosing block.

如果lettry块内定义了变量,则它不会在catch(或finally)块内的范围内。它需要在封闭块中定义。

For example, in the following code block, the console output will be "Outside":

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

let xyz = "Outside";

try {
    let xyz = "Inside";

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

回答by gdoron is supporting Monica

  • In javascript only functions create a new context -closure.
  • Every definition of a variable is really a declaration of the variable at the top of its scope and an assignment at the place where the definition is.
  • 在 javascript 中,只有函数会创建一个新的上下文闭包。
  • 变量的每个定义实际上都是在其作用域顶部的变量声明和在定义所在位置的赋值。

var

无功

  • function-scoped
  • hoist to the top of its function
  • redeclarations of the same name in the same scope are no-ops
  • 函数作用域
  • 提升到其功能的顶端
  • 在同一范围内重新声明同名是无操作的

You may want to read MDN scope cheat sheet

您可能想阅读MDN 范围备忘单

Due to hoistingYou can even do things like this:

由于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

演示

So the foofunction is converted to something like this:

所以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
}?

My question is: what is the scope of magicVar and is it okay to pass it into magicFunction as I've done?

我的问题是:magicVar 的范围是什么,是否可以像我所做的那样将它传递给 magicFunction?

Define okay..., Yes the code is valid, but it's less readable then if the variables declarations were on the top, that's all.

定义好的...,是的,代码是有效的,但是如果变量声明在顶部,那么它的可读性就会降低,仅此而已。

回答by Marc

Due to javascript "hoisting" (google it), your variable declaration code gets translated as:

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

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

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

} //end of your function

"Hoisting" moves all variables declarations to the top of the function. So magicVaris available everywhere in the function, but it's undefined until you give it a value.

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

Your variable has function scope.

您的变量具有函数作用域。

回答by zneak

With var, variables exist from the beginning of the function to the end of it, no matter where they are declared, or even if the statement is actually ever reached. They will, however, be undefineduntil they are assigned another value.

使用var,变量从函数的开头一直存在到函数的结尾,无论它们在哪里声明,或者即使语句实际上已经到达。然而,它们将undefined一直存在,直到它们被分配另一个值。

So in your case, if somethingis false but somethingelseis true, you will call magicFunctionwith its first argument being undefined.

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

The letkeyword, created in Javascript 1.9 and available (as of today, May 3rd2012, and as far as I know) only in Firefox, declares variables with the scoped semantics you're probably used to.

let关键字,在Javascript 1.9创建和提供(截至今日,5月3 RD2012,而据我所知)只在Firefox中,声明了你可能使用的范围的语义变量。

回答by Nikhil_k

I agree with variable hoisting and function hoisting, I would like to emphasis two import points.

我同意变量提升和函数提升,我想强调两个重点。

  • Identifier Defined in Catch parameter is i.e. err/e(error) , is scoped to Catch defined block.

  • Function first hoisting. example :

        b(); // output : 3
        var b = 2;
        function b(){
         return 3;
        }
    
  • Catch 参数中定义的标识符是 ie err/e(error) ,作用域为 Catch 定义的块。

  • 功能第一吊装。例子 :

        b(); // output : 3
        var b = 2;
        function b(){
         return 3;
        }