JavaScript scope in a try block

后端 未结 6 1780
礼貌的吻别
礼貌的吻别 2020-12-30 20:37

Say I\'m trying to execute this JavaScript snippet. Assume the undeclared vars and methods are declared elsewhere, above, and that something and something

相关标签:
6条回答
  • 2020-12-30 20:47

    Javascript has function scope. That means that magicvar will 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.

    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.

    Your example will pass undefined into magicFunction if something is false, because magicVar hasn't been assigned to anything.

    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

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

    POP QUIZ: What does the following code do?

    (function() {
      x = 2;
      var x;
      alert(x);
    })();
    alert(x);
    
    0 讨论(0)
  • 2020-12-30 20:49

    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;
          }
      
    0 讨论(0)
  • 2020-12-30 20:54

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

    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 magicVar is available everywhere in the function, but it's undefined until you give it a value.

    Your variable has function scope.

    0 讨论(0)
  • 2020-12-30 21:07

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

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

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

    let xyz = "Outside";
    
    try {
        let xyz = "Inside";
    
        throw new Error("Blah");
    } catch (err) {
        console.log(xyz);
    }
    
    0 讨论(0)
  • 2020-12-30 21:07

    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 undefined until they are assigned another value.

    So in your case, if something is false but somethingelse is true, you will call magicFunction with its first argument being undefined.

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

    0 讨论(0)
  • 2020-12-30 21:09
    • 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.

    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

    Due to hoisting You can even do things like this:

    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 foo function is converted to something like this:

    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?

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

    0 讨论(0)
提交回复
热议问题