Why does re-declaring an argument inside of a try/catch throw a ReferenceError?

后端 未结 4 627
北恋
北恋 2020-12-28 13:20

I mistakenly wrote a re-declaration of an argument as a const in a function and instead of throwing SyntaxError: Identifier \'bar\' has already been decla

相关标签:
4条回答
  • 2020-12-28 13:55

    Because const declarations are block scoped, the const bar declaration gets hoisted to the start of the block. (Just after try {)

    That means that bar isn't actually defined when you try to log it, because the hoisting overrides / hides the parameter bar.

    0 讨论(0)
  • 2020-12-28 13:57

    It's a myth that const and let aren't hoisted at all. They're half-hoisted. :-) That is: Within a block, if const bar or let bar (or class bar { } for that matter) appears anywhere in that block, then bar cannot be used prior to that declaration in the block — even if it exists in a containing scope. This area between the beginning of the block and the declaration is called the Temporal Dead Zone:

    function foo(bar) {
      // `bar` is fine here
      try {
          // Temporal Dead Zone, `bar` cannot be used here
          console.log(bar);
          // End of TDZ
          const bar = 123;
          // `bar` would be fine here
      } catch(err) { console.log(err) }
    }
    foo(456);    
    
    0 讨论(0)
  • 2020-12-28 14:10

    Taken from here https://tylermcginnis.com/videos/var-let-const/

    var is function scoped and if you try to use a variable declared with var before the actual declaration, you'll just get undefined. const and let are blocked scoped and if you try to use a const or let variable before the declaration you'll get a reference error.

    0 讨论(0)
  • 2020-12-28 14:17

    Constants are block-scoped, much like variables defined using the let statement.

    From this MDN article.

    Since you wrapped bar inside a block of braces, its definition is relative to that block. And because you have another bar declaration inside of that block, despite being after the call to it, the compiler will attempt to use this newly defined bar instead of the passed-in parameter. Rename them as separate parameters to mitigate confusion, since one can assume they are holding different data because of your declaration.

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