Hoisting for variable and functions

A variable is a container used for storing values which we might referencing multiple times in our program. We can use let, const and var to declare a variable in javascript program. In this post, I will demonestrate the difference between the three declaration keywords, and hoisting concept for each one of them.

Variable Scope

Scope in JavaScript refers to the current context of code, which determines the accessibility of variables to JavaScript. The two types of scope are local and global:

  • Global variables are those declared outside of a block
  • Local variables are those declared inside of a block

In the examples below, I will illustrate the difference between function- and block-scoped variables using var and let.

var bonus = true; 
var salary = "$1000";
if(bonus) {
var salary = "$500"
console.log(`${salary}`)
}
console.log(`${salary}`)
// OUT-PUT
//$500
//$500
var bonus = true; 
let salary = "$1000";
if(bonus) {
let salary = "$500"
console.log(`${salary}`)
}
console.log(`${salary}`)
// OUT-PUT
//$500
//$1000

Hoisting

The Javascript engine treats all the variable declared with a var keyword as they are declared at the top layer of the scope wether it is declared globally or inside a function. No matter where the actual declaration occurs. So, the variable can be avaliable before their declaration!!!So, If we attempt to use a variable before it has been declared and initialized, it will return undefined.

console.log(x); 
var x = 3
// undefined

And if we removed the var keyword it will through out a different error which is reference error that’s is exactly what hoisting is.

if we need to declare a variable called salary, we can declare it like so:

The line above consists of :

  1. Declare avariable using key word var
  2. The variable name salary - identifier
  3. The assignment operator using = syntax
  4. The value being assigned to a string datatype $1000

Now our javascript intpreter saves a variable called salary in the memoy, and can be used.

var userName = 'username'; 
function name() {
// A condition that should not affect the outcome of the code
if (false) {
var userName = 'newName';
}
console.log(userName);
}
name();
// OUT-PUT is undefined

In this example, we declared userName to be ‘username’ globally. Depending on an if statement, userName could change to ‘newName’, but since the condition was false it should not have affected the value of userName. Instead, userName was hoisted to the top of the name() function, and the value became undefined.

This can be a problem in our program, and be a source for unpredictable bugs. So, ES6 came out with a new variable declaration keywords let and const. Both let and const have the same concept of var; however, they are different in the hoisting and scope concept.

// Initialize `myName` in the global scope 
let myName = true;
function name() {
// Initialize myName in the function scope
if (myName === 'username') {
let myName = false;
} console.log(myName);
}
name();
//OUT-PUT is true

We can summarize the declaration keywords as the following table.

It is recommended to use const in declaring variables and assigning a function, and use let for loops and reassignment. For var it is recommended to avoid using it.

Arrow functions

An arrow function is different from a normal function in only three ways:

  1. It always has a bound this.
  2. It can’t be used as a constructor: There is no internal method [[Construct]] (that allows a normal function to be invoked via new) and no property prototype.
  3. As arrow functions are an ECMAScript.next-only construct, they can rely on new-style argument handling (parameter default values, rest parameters, etc.) and don’t support the special variable arguments. Nor do they have to, because the new mechanisms can do everything that arguments can.

Apart from these simplifications, there is no observable difference between an arrow function and a normal function. For example, typeof and instanceof can be used as before:

typeof () => {} 
// OUT-PUT is a 'function'
() => {} instanceOf Function
// OUT-PUT is true

Named vs Anonymous Functions

Named functions are useful for a good debugging experience, while anonymous functions — functions without a name, provides context scoping for easier development. One of the most famous use cases for anonymous functions are Immediately Invokable Function Expressions, which immediately creates and invokes the contents of the function.

(function() { 
console.log('myName');
// myName
})();

However, as we explained earlier, named functions are function declarations that are hoisted during the engine interpreting phase. The engine define the named function as a block then construct an execution context when the function being invoked.

Hope that this post helped you figured out the difference between variables in javascript. Please show your support for keeping me motivated to write more contents by 👏 👏 👏 and following me on twitter on @salmaeng

Data Engineer at Fortune Magazine. https://www.linkedin.com/in/salma-elshahawy/