So what defines the boundaries of scope? Scope is relative to the authored code as it was at lexing time, and depends on whether you’re using
var is referenced within a function, the current scope is the bounding curly braces of that function. A variable declared within the function can’t be accessed directly outside of that function (without explicitly returning it or assigning it to a higher scoped variable).
The global scope is the top boundary of scope, and
vars declared in global scope can be accessed on the
window object in a browser environment (but not
consts). Scopes are nested for functions within global scope, and again for functions within functions.
If the function is inside another function and the variable can't be found in that function scope, scope looks to the bounds of the parent function for the variable.
As mentioned, there are differences in using
const when it comes to scope. Declaring a
var defines it’s scope within the current function (or global scope if it’s not within a function).
const on the other hand defines scope for that property within the current block, and not confined to just function bounds.
A block is usually deemed to be the current block of code within curly braces (but not always), and blocks can be created anywhere the curly braces syntax is legal.
As in the last example with the explicit curly braces block, creating blocks shows the JS engine that the enclosing
consts can be garbage collected after use, as they can’t be accessed outside of that block, which is a performance improvement.
There are two types of scope lookup, a left hand side (LHS) reference and right hand side (RHS) reference. An LHS reference lookup occurs when a variable is being assigned, whereas an RHS reference looks to scope to find the source and value of a variable or function. An LHS reference will therefore occur with an assignment operation using
= or when an argument is passed to a function, where the assignment of the function parameter is implicit.
There's a difference here in what happens if the lookup fails to find anything in scope. For an assignment lookup (LHS), if nothing has been found up to and including the global scope, then the global scope will declare the new variable as a
var. If the code is authored in strict mode however (
ReferenceError when trying to assign
If a lookup to scope to find the source of a variable (RHS) finds nothing declared for that identifier name then again, a
ReferenceError will be thrown. If a variable is found but the code is trying to do something that's not allowed for that variable data type, (for example, you try to perform an array method on an integer), then a
TypeError is thrown.
You can see the difference between a ReferenceError and a TypeError, an indication as to what may have occurred in your code when you come across them.
If you have any questions or comments or want to connect, you can follow me on Twitter, or sign up to the newsletter in the footer for front-end articles to your inbox 👇