Below content is an excerpt from my book – “JavaScript for C# developers“.
Scope in javascript works completely different from how it works in C#. In javascript, we have both block scope and function scope. However, the predominant scope used in javascript is function scope till ES5. We would discuss later in this chapter about the rules which javascript engine uses to decide whether to apply block scope or function scope.
Characteristics of Function scope:
- Each function creates a new scope:
As discussed earlier, in javascript, we can create a function inside another function. This inner function creates a completely new scope.
Let’s discuss with an example. Consider below code snippet where we have declared function by name ‘A’ which creates a scope(‘Scope A’) and then we declare another function by name ‘B’ inside ‘function A’ which in turn would create another scope(‘Scope B’)
If you declare any variable outside of ‘function A’, we could say that variable is in global scope as that variable is not enclosed within any function.
2. All declarations are ‘Hoisted’
Hoisting is a mental model of execution of javascript code. As per this model, all variable and function declarations will be moved to the top of the current scope.
Before discussing ‘hoisting’ with examples, let us discuss about declaration and execution statements in javascript.
In the below code snippet – first line, which declares variable by name ‘a’ , is considered as a declaration statement whereas the second line, which assigns a value of 5 to the variable ‘a’ is an execution statement.
The primary difference between declaration statements and execution statements is that in declaration statements no evaluation is done whereas in execution statements, evaluation or calculation is done.
In the above code snippet, first 3 lines correspond to a function declaration whereas the last line is execution of the declared function.
When a function is at the right side of an statement, the statement becomes function expression. Function expression is also considered as an execution statement and hence would not be hoisted. Below is an example of function expression, which would not be hoisted.
Consider the below code snippet using which we discuss about hoisting.
Hoisting suggests all the variable and function declarations and only the declarations are moved to the top before javascript engine executes your code. Let us step through each line of the above code snippet and discuss how hoisting works.
First line is a declaration of ‘function A’. As this declaration statement is already in global scope, there is no need to be moved anywhere. As ‘console.log’ statement in second line is not a declaration statement, there is no need to move this statement too. Statement in third line contains both declaration and execution parts – it declares a variable (declaration) and it initialises the variable(execution) with value 5. So, hoisting moves only the declarative part of this statement to the top. Third line is a ‘console.log’ statement which is an execution statement and hence hoisting would not do anything.Line 7 is a function call, an execution statement and hence hoisting would not do anything to this statement too.
After hoisting, the code would look like below
The main difference between the code before hoisting and after hoisting is that the statement ‘var a = 5’ is split into two statements as declarative and execution statements. Declarative statement is moved to the top whereas execution statement stayed at where it was.
After hoisting, javascript engine executes your code. At line 3, the variable ‘a’ would not have any value and hence it would print undefined. At line 4, value 4 is initialised to the variable a. So, ‘console.log’ statement at line 5 would print 5.
Please note that the concept of hoisting is just a mental model on execution of your javascript code and the process of actual execution differs. In the book, we’re going to discuss another model for execution of javascript code, which is more close to the actual execution of the javascript code.
3. Duplicate declarations are ignored
Unlike C#, duplicate variable declarations in function scope are ignored. Below code snippet will not throw any error and would print 5.
What would get printed if the below code is executed?
It would print 6, as the above code is transformed something like below
This is how function scope works in JavaScript. Please let me know your thoughts in comments.