Why does the first console log print out "James" when it should print out "Ken"? Shouldn't the let 'student' variable be scope to the 'if-statement' and retain its value as "Ken"? Also, shouldn't there be an error as I'm redeclaring the same variable name 'student'?
(function (){
let student = {name: 'James'};
function createStudent(name){
if(true){
let student = {name: name};
}
return student;
}
console.log(createStudent('Ken'));
console.log(student);
})();
let
is block scoped so this line of code:
let student = {name: name};
is scoped only to the brackets inside the if
statement. So, when you later do
return student;
outside of the if
block and outside of where the other student
variable was defined, that variable is no longer in scope so the only student
variable that is in scope is the James
one.
Here's an annotated version:
(function (){
let student = {name: 'James'};
function createStudent(name){
if(true){
// define new student variable that is only in scope
// within this block
let student = {name: name};
}
// here, the student variable on the previous line is no longer
// in scope so referencing it here sees the first declaration
return student;
}
console.log(createStudent('Ken'));
console.log(student);
})();
Shouldn't the let 'student' variable be scope to the 'if-statement' and retain its value as "Ken"?
It is block scoped to the if
statement. But, when you do the return
, it's outside that block so there is no access to the Ken
student variable any more so the only one that is in scope is the James
one.
Also, shouldn't there be an error as I'm redeclaring the same variable name 'student'?
It is not an error to define a variable that was already defined in a higher scope. Instead, the new declaration shadows or hides the other declaration within that scope, temporarily overriding it within that scope.
The let
and const
unlike var
create local scope inside block statements. You are not getting an error because the new variable
shadows
the one outside the scope.