- JavaScript has function-based scope. Each function you declare creates a bubble for itself. All variables and functions created inside a function cannot be accessed outside of it.
- Variable collision needs to be avoided as a scope is accessible to all the nested scopes.
- Libraries loaded in the program can easily collide with each other if they do not properly hide their internal private functions and variables. Libraries typically create a single variable that is sufficiently unique in the global scope and then add properties on that object like
var myLibrary {
greet: "Have a nice time",
doSomething(): function() { .. }
doSomethingElse(): function { .. }
}
- Another option is to use modern package managers to do the module management which can help us do explicit imports into the scope.
- JS also offers a way to create a function that doesn't pollute the current scope and has need not to be called separately. This tool is called function expression.
var a = 2;
// We start the function with `(` treated the function as function declaration
(function foo() {
var a = 3;
console.log(a); //3
})(); // This is added to execute the function on the spot (IIFE)
foo(); // foo is not defined
- Anonymous function expressions are also commonly seen in JS. These are function expressions with no name.
setTimeout( function() {
console.log("I waited 1 second!");
}, 1000);
- Immediately Invoked function expressions (IIFE) are having a () in the end to execute it. There are two ways:
( function iife() { .. })()
****or ****( function iife() { .. }())
.
- We can pass argument to IIFE like
var a = 2;
(function IIFE(global) {
var a = 3;
console.log(a); // 3
console.log( global.a ); // 2
})( window );
console.log( a ); // 2
- Block scope can be observed in JS at various places like
with
, try/catch
, let
and const
.
- The frowned upon way of doing things using
with
has a block scope
var obj = {
a: 1,
b: 2,
c: 3
};
// using with()
with(obj) {
a = 2;
b = 3;
c = 4;
}
a; // not defined
try/catch
also has a block scope which was added in ES3
try {
undefined(); // illegal operation to force error
} catch (err) {
console.log(err); // works!
}
err; // not defined
let
was added in ES6 and it is the most common way to create block as scope. let
isn't hoisted (we will understand more about this in next chapter).
{
let hello = "world";
}
hello; // not defined
let
also helps do better garbage collection