Hoisting
simple gives higher specificity to javascript declarations. Thus, it makes the computer read and process declarations first before analyzing other code in program.
Note:
Hosting does not mean JavaScript rearranges or move code above one anothers.
E.g.
console.log(name); // Uncaught ReferenceError: name is not defined
let name = 'Deepa';
variables declared with let and const are hoisted but not initialized with a default value.
Accessing let or const before it's declared will give: Uncaught ReferenceError: can't access before initialization
Remember the error message tells variable is initialized somewhere.
When interpreter hoists a variable declared with var, it initialized its value to undefined, unlike let or const.
E.g.
console.log(name); // undefined
var name = 'deepa';
console.log(name); // deepa
Now let's analyze this behaviour:
var name;
console.log(name); // undefined
name = 'partha';
console.log(name); // partha
Remember, the first console.log(name) outputs undefined because name is hoisted, and given a default value (not because variable is never declared).
Using undefined variable will throw ReferenceError
console.log(name); // Uncaught ReferenceError: name is not defined
Now let's see if we don't declare var what happens.
console.log(name); // partha
name = 'partha';
name = assigning a variable that's not declared is valid.
JavaScript let us access variable before they're declared. This behaviour is an unusual part of javascript and can lead to errors.
Using variable before it's declaration is not desirable.
The reason why we get reference error when we try to access let or const before its declaration is Temperal Dead Zome
- The TDZ starts at beginning of the variables enclosing scope and ends when it is declared.
- Accessing variable in TDZ gives ReferenceError
E.g.
{
// start of foo's TDZ
let bar = 'bar';
console.log(bar); // bar
console.log(foo); // ReferenceError: // Because we're in TDZ
let foo = 'foo';
// end of foo's TDZ
}
- type of TDZ for let or const:
ReferenceError
- type of TDZ for var:
undefined
Function declarations are hoisted too. Function hoisting allows us to call function before it is declared or defined.
foo();
function foo() {
console.log('foo'); // foo
}
Note:
only function declaration are hoisted not function expressions.
E.g.
foo(); // Uncaught TypeError: foo is not a function
var foo = function() {
}
bar(); // Uncaught ReferenceError
let bar = function() {
}
Uncaught ReferenceError: can't access 'bar' before initialization similarly for const
.
foo(); // Uncaught ReferenceError: foo is not defined