I am sure the question title is complicated but my problem is a little bit tough. I will also try to be instructive in this question.
I am working on a new blog post about hoisting but I am stuck with a question.
Lets first give an example of hoisting.
function logCar() {
console.log('Car: ' + carName);
}
logCar();
var carName = 'Yoyota';
So we expect a log without an error: Car: undefined
. Behind the scene, it is being converted to the code below.
var carName;
function logCar(){
console.log('Car: ' + carName)
}
logCar();
carName = 'Yoyota';
So it is working without an exception. Let's try using let
which is not hoisted.
function logCar() {
console.log('Car: ' + carName);
}
logCar();
let carName = 'Yoyota';
This code immediately throws a ReferenceError: carName is not defined
. So I can clearly understand that let is not hoisted. let carName;
is not being moved to the top of block scope.
Then I wanted to use parent scope as a lexical scope of logCar
and it works perfectly and outputs Yoyota
without an error.
let car = 'Yoyota';
const logCar = () => {
console.log(car);
}
logCar();
As I am using let I can also change the car name for my logCar
scope without affecting parent.
let car = 'Yoyota';
const logCar = () => {
let car = 'MWB';
console.log(car);
}
logCar();
console.log(car);
It outputs exactly what I am expecting. First 'MWB', then 'Yoyota'. Then, I wanted to redeclare variable
car in logCar
scope but before declaring it I wanted to use the variable
from lexical scope.
let car = 'Yoyota';
const logCar = () => {
console.log(car); // ReferenceError: car is not defined
let car = 'MWB';
console.log(car);
}
logCar();
Then I got a ReferenceError: car is not defined
error. But why? car
should be defined on the lexical scope as it works on the previous example? Why adding let car = 'MWB'
to that scope makes it throw error while let is not being hoisted?