Let variables and block scope

2019-09-08 16:01发布

问题:

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);
})();

回答1:

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.



回答2:

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.