Block-scoping
When a variable is declared using let
, it uses what some call lexical-scoping or block-scoping. Unlike variables declared with var
whose scopes leak out to their containing function, block-scoped variables are not visible outside of their nearest containing block or for
-loop.
function f(input: boolean) { let a = 100; if (input) { // Still okay to reference 'a' let b = a + 1; return b; } // Error: 'b' doesn't exist here return b; }
Here, we have two local variables a
and b
. a
’s scope is limited to the body of f
while b
’s scope is limited to the containing if
statement’s block.
Variables declared in a catch
clause also have similar scoping rules.
try { throw "oh no!"; } catch (e) { console.log("Oh well."); } // Error: 'e' doesn't exist here console.log(e);
Another property of block-scoped variables is that they can’t be read or written to before they’re actually declared. While these variables are “present” throughout their scope, all points up until their declaration are part of their temporal dead zone. This is just a sophisticated way of saying you can’t access them before the let
statement, and luckily TypeScript will let you know that.
a++; // illegal to use 'a' before it's declared; let a;
Something to note is that you can still capture a block-scoped variable before it’s declared. The only catch is that it’s illegal to call that function before the declaration. If targeting ES2015, a modern runtime will throw an error; however, right now TypeScript is permissive and won’t report this as an error.
function foo() { // okay to capture 'a' return a; } // illegal call 'foo' before 'a' is declared // runtimes should throw an error here foo(); let a;
For more information on temporal dead zones, see relevant content on the Mozilla Developer Network.
Please login to continue.