The variables have a scope or visibility. The scope of a variable determines which part of the program can access it. We can define a variable in three ways, so as to limit their visibility. One is the local variable or block variable, which has the scope of a code block (block scope or local scope). The second one is a function variable or class variable which has the function/class scope. The last one is the global variable, which can be accessed anywhere in the program (global scope).
The scopes are important. without scopes, the variables will be visible everywhere. This forces us to keep track of the names of all declared variables so that we do not accidentally reuse one. And if a variable has the wrong value, you have to scan the entire code base for the bug, because the value may have been altered by any statement.
Table of Contents
Variable Scope
The Typescript variable can be in three scopes depending on how & where you have defined them.
- Global Scope
- Function Scope or Class Scope
- Local Scope or Block scope
Global Scope
Define the global variable outside of any function/ class or code block and they become part of the global scope. We can use them anywhere within the program.
The following example shows a variable, globalVar
defined outside of any function or code block. You can access it anywhere in the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | //defined gloablly. outside of any function or code block //You can access it from anywhere including the function, code block, nested funciton etc let GlobalVar=100; function someFn() { //function console.log(GlobalVar) if (true) { //code block console.log(GlobalVar) } function nested() { //nested function within someFn1 console.log(GlobalVar) } } for (let c = 0; c < 3; c++){ //code block console.log(GlobalVar); } function someOtherFn1() { //another function console.log(GlobalVar) } console.log(GlobalVar) //outside of any function/code block |
Function Scope
The function or class variables defined inside the function/class etc are function scoped. They are available to use anywhere within the function. You cannot use them outside the function.
In the following example, the variable fnVar
is defined inside the someFn
function. This makes it function scoped. You can access it from within the someFn
. You can also, access it from the code block or nested
function within the someFn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | function someFn() { //Variable defined inside the function. //can be accessed from anywhere inside the function //including the nested function or code block let fnVar=10 console.log(fnVar) //can be accessed here if (true) { console.log(fnVar) //can be accessed here } function nested() { console.log(fnVar) //can be accessed here } } function someOtherFn() { console.log(fnVar) //cannot be accessed here } for (let c = 0; c < 3; c++){ console.log(fnVar); //cannot be accessed here } console.log(fnVar) //cannot be accessed here |
Nested function
The example below defines a fnNestedVar
inside the nested function. We can access this variable only within the nested function and its nested functions and code blocks. But not from the parent function or anywhere outside the nested function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | function someFn() { if (true) { } function nested() { //defined inside nested function //can be accessed only within the nested function and its nested functions & code blocks let fnNestedVar=100 console.log(fnNestedVar) } console.log(fnNestedVar) //cannot be accessed here } function someOtherFn() { console.log(fnNestedVar) //cannot be accessed here } for (let c = 0; c < 3; c++){ console.log(fnNestedVar); //cannot be accessed here } console.log(fnNestedVar) //cannot be accessed here |
Local scope or Block Scope
The local variables are declared inside a code block. They are also known by the name block variable
The code block is a section of source code clearly delimited using the curly braces. For example inside the if/try/catch/while/for block.
The example below shows a localVar
declared inside the if
condition. The scope of localVar
ends where the curly braces of the if condition ends. Outside the code block, you cannot access it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | function someFn() { if (true) { //defined locally //Its scope ends where curly braces ends let localVar=1000 console.log(localVar) //ok } console.log(localVar) //Error function nested() { console.log(localVar) //Error } } for (let c = 0; c < 3; c++){ console.log(localVar); //Error } function someOtherFn() { console.log(localVar) //Error } console.log(localVar) //Error |
var is an exception
The keyword var
is an exception to the above rule. var
supports only global & function scope. So if you define a variable inside a code block, it is scoped to enclosing function and not to the code block.
That is the main reason why let
exist. To bring the local scope to the Javascript. The let
is part of the ES2015 or ES6 specification.
For Example, take the above example and change let
to var
. You can see that the localVar
is not accessible outside the code block and also in the nested function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | function someFn() { if (true) { //defined locally using var, which is function scoped //You can access it any where within the someFn //This is the major difference between var & let var localVar=1000 console.log(localVar) //ok } console.log(localVar) //ok function nested() { console.log(localVar) //ok } } for (let c = 0; c < 3; c++){ console.log(localVar); //Error } function someOtherFn() { console.log(localVar) //Error } console.log(localVar) //Error |
Declaring the variable
There are three keywords, that you can use to declare a variable in Typescript. They are let
, var
or const
keyword. The scoping rules differ between them.
The var
supports function & global scopes as shown in the example above.
The let
& const
support all three scopes.
The following is demonstrates the use of all three scopes. The first example uses var
to define and the second example uses let
.
The var scope example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var GlobalScope=1; function someFunc() { var FunctionScope=2; if (true) { var BlockScope=3; console.log(GlobalScope); console.log(FunctionScope); console.log(BlockScope); } console.log(GlobalScope); console.log(FunctionScope); console.log(BlockScope); //No Error here } console.log(GlobalScope); console.log(FunctionScope); //error console.log(BlockScope); //error |
The let scope example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | let GlobalScope=1; function someFunc() { let FunctionScope=2; if (true) { let BlockScope=3; console.log(GlobalScope); console.log(FunctionScope); console.log(BlockScope); } console.log(GlobalScope); console.log(FunctionScope); console.log(BlockScope); //error } console.log(GlobalScope); console.log(FunctionScope); //error console.log(BlockScope); //error |
Example using for loop
In the following example, we use the var
keyword to declare the variable i
, which inside the code block. But since var
is function scoped, we can access the i
even outside the for loop. Hence it is accessible to the console.log, which is outside
1 2 3 4 5 6 7 8 9 | function countMe(){ for (var i = 0; i < 10; i++){ console.log(i) } console.log('Counted: ' , i); //No Error here } countMe(); |
Now change from var to let
. The compiler emits an error TS2304: Cannot find name ‘i’.
1 2 3 4 5 6 7 8 9 | function countMe(){ for (let i = 0; i < 10; i++){ console.log(i) } console.log('Counted: ' , i); //results in error here } countMe(); |
Summary
The Typescript variables have three scopes. Global, Function and local. Using var
you can create global & function variable. While We use let
& const
to all the three.