JavaScript Scope & Hoisting: what determines how your code works?
Understanding JavaScript Scope and Hoisting is the difference between writing reliable, debuggable code and creating code that is full of mystery bugs. You’ve probably come across a variable behaving erratically or a function working before it was defined, and you’ve been left scratching your head.
Scope defines where you’re able to use your variables and functions. Hoisting defines how javascript moves variable and function declarations to the beginning of their respective scopes prior to running the code. With both of these concepts combined, you’ll have a good idea about most of the quirks of the javascript programming language.
Once you begin to learn JavaScript Scope and Hoisting, you may initially find the behavior to be counterintuitive. Once you understand the rules behind the behavior, however, all will make sense. So, here are five key areas of study that will help you better comprehend how javascript handles your variables and functions.
Important areas of study about JavaScript Scope and Hoisting
1. Global Scope: the big picture
The Global Scope is where all your code resides. It is the base scope where all variables created outside of a function or block reside. Most often in web development (browsers), the global object is window. Most often in server-side development (Node.js), the global object is global.
Variables that are created in the Global Scope can be used anywhere in your code. Although global variables seem like they’d be beneficial in many situations, they also bring significant risk. If there are too many variables living in the Global Scope, you could end up having naming conflicts, confusing bugs due to interactions with other parts of your code, and ultimately, poor maintainability.
Anytime you create a variable without declaring it using let, const, or var (in non strict mode), you inadvertently create a global variable. This happens nearly every time, so always Declare your variables using One of these keywords.
Knowing Global Scope is important when studying JavaScript Scope & Hoisting. However, learning local scopes where variables can only be seen within specific regions of your code is what really allows you to take advantage of the power of scopes.
2. Function scope: traditional boundary
Prior to ecmascript 6 (released in 2015), javascript only offered two types of scopes: global and function. Variables declared with var inside of a function were only available to that function; i.e., they weren’t accessible outside of it.
Function scoped variables are ideal for encapsulating logic. Each function can contain its own variables and logic without affecting the surrounding code. Once a function is finished executing, its local variables are candidates for garbage collection.
There is One quirk to var though; it isn’t block scoped. Variables declared with var inside of an if statement or a for loop are technically scoped to the closest function; not the block they were created in. Many developers are surprised by this and it is One of the most common causes of bugs.
Function scope is the old way of doing things in terms of JavaScript Scope & Hoisting. However, with modern JavaScript you have another level of granularity for controlling what you can see and manipulate.
3. Block scope: new school
Ecmascript 6 brought us let and const two block scoped keywords. Anything enclosed in { } (such as an if statement or a for loop) creates a new block. Variables declared inside of blocks with either keyword can only be seen inside those blocks.
Block scoped variables with let and const eliminate unintended exposure of data, making your code cleaner and safer overall.
You can Declare a variable inside of an if block, and it won’t exist once the block exits. Similarly, each iteration in a for loop will get its own binding with let.
Use let for variables that will change; use const for variables that will remain constant. Both are block scoped variables; thus providing better protection against Hoisting related issues. As stated earlier, using let/const instead of var is preferred, especially since they provide block scoping. Therefore, it is now considered the standard approach to JavaScript Scope & hoisting in modern environments.
4. Hoisting: the deceptive lift
Hoisting refers to how javascript lifts variable and function declarations to the top of their containing scope when compiled (i.e., when your script begins to run). Thusly, you can refer to a variable or function before it appears in your code.
However, it’s worth noting that Hoisting doesn’t lift assignments to variables; it simply lifts variable/function declarations. For instance, for var, the variable is lifted and initialized with undefined, which is why you can access the variable before the line where you assign a value to it, it will be undefined (not throw an error).
On the other hand, for let and const, only the declaration is lifted and not assigned. If you attempt to access these variables before they are declared, a ReferenceError will be thrown because they exist in a “temporal dead zone” (which we’ll discuss further below).
A function declaration is fully hoisted; therefore you can call a function before its definition and it will behave normally. On the other hand, function expressions (even those using var) do not experience Hoisting like function declarations do; rather only the variable is lifted and not assigned.
By becoming familiar with how javascript performs Hoisting based upon how you Declare your variables/functions, you will be able to predict where certain lines of code will produce runtime errors versus expected output. Understanding JavaScript Scope and Hoisting provides you knowledge about why certain lines of code produce runtime errors while others don’t.
5. Temporal dead zones (tdzs) & best practices
A temporal dead zone (also referred to as TDZ) represents the duration between when you enter a given scope and when you encounter an actual declaration of a let or const variable. Throughout this period, although a variable exists, it cannot be referenced/accessed.
As mentioned previously, this is a deliberate feature designed to detect potential errors. The TDZ ensures that you Declare your variables prior to utilizing them; producing much cleaner/predictable code compared to using var (where undefined would be returned silently). Unlike var where nothing is reported to indicate an issue existed; let and const will report an error indicating that something went wrong.
To avoid TDZ issues altogether; ensure that you place variable declarations at the beginning of their respective scopes. Regardless of whether you choose to utilize var, let, or const this is always going to result in less confusion due to Hoisting behaviors that may arise elsewhere.
Conclusion
All in all, the five topics above give you a solid foundation for comprehending how javascript handles your variables and functions including the concept of JavaScript Scope and Hoisting.
- Firstly, minimize usage of global variables, use local scopes wherever possible.
- Secondly, prefer let/const over var, these two provide block-scoping and therefore offer protection against various forms of Hoisting-related issues.
- Thirdly, ensure that your variable declarations occur at the beginning of their respective scopes, this eliminates any confusion associated with Hoisting behaviors.
- Lastly, remember that functions can be called before they’re executed, provided they’ve been declared via function declaration syntax. Additionally, function expressions aren’t hoisted, only the variable is lifted (and initialized to undefined); with respect to var.
- Using let/const will protect you from attempting to access these variables before their declaration, resulting in a ReferenceError which occurs due to their presence in a temporal dead zone.
- Finally, use const exclusively when dealing with values that will never change, this signifies intent clearly and prevents accidental modification.
- Create simple test cases and try to guess what will happen prior to running your tests; this will strengthen your ability to accurately predict what javascript will do in various scenarios.
For deeper dives into these topics, JavaScript.info’s guide to variable scope offers clear explanations and interactive examples. Another excellent resource is MDN’s documentation on scope and hoisting, which covers the technical details thoroughly.
New to HTML? Start Here: HTML Tutorial for Beginners: Your Complete Introduction to HTML Basics
New to CSS? Start Here: CSS Introduction: Master 5 Core Concepts Easily
New to JavaScript? JavaScript Introduction: 5 Proven Steps to Learn JS
[INSERT_ELEMENTOR id=”122″]

