JavaScript Closures
- What exactly is Closure in JavaScript?
- Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.
- In other words, a closure gives you access to an outer function's scope from an inner function.
- Here environment is referred as lexical environment.
- Example:
- Lexical Environment:
- Used to define the association of Identifiers by giving them some meaning and also manage them in the code.
- Lexical Environment consists of an Environment Record that consist all the existing identifiers and their relations within the lexical environment.
- Lexical nesting structure which means there is an outer environment for an inner environment, but the outer environment can also have an outer environment and so on. The only lexical environment is the global environment which further has no outer environment for itself. This can be referred to as layers.
- A new Lexical Environment is created each time a function is called.
- Scope Chain:
- Based on the above definition, we know that an environment has access to its parent’s environment, and its parent environment has access to its parent environment, and this goes on.
- The set of identifiers is that is accessible by each environment is known as 'scope '.
- Every closure has three scopes:
- Local scope (Own scope)
- Enclosing scope (can be block, function, or module scope)
- Global scope
- We can also represent the scopes in a nested form in a hierarchical chain of environments which is known as ' Scope Chain '.
- This is also known as “lexical scoping”.
- Example:
- Emulating private method with closure:
- Java Script allows you to declare methods as private, meaning that they can be called only by other methods in the same class.
- Private methods aren't just useful for restricting access to code. They also provide a powerful way of managing your global namespace.
- Example:
- The shared lexical environment is created in the body of an anonymous function, which is executed as soon as it has been defined also known as an IIFE(Immediately Invoked Function Expression)
- Creating closures in loop : A common mistake
- Creating closure in JavaScript becomes a little more complicated when working with loops, as it causes undesirable behavior.
- The reason for this is that the functions assigned to form closures; they consist of the function definition and the captured environment from the function's scope.
- Three closures have been created by the loop, but each one shares the same single lexical environment, which has a variable with changing values.
- This is because the variable is declared with var and thus has function scope due to hoisting.
- Performance considerations:
- It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.
- When creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned.