让变量和块作用域

Let variables and block scope

为什么第一个控制台日志打印出 "James" 而它应该打印出 "Ken"? let 'student' 变量不应该是 'if-statement' 的范围并保留其值作为 "Ken" 吗?另外,当我重新声明相同的变量名 '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 是块范围的,所以这行代码:

let student = {name: name};

的范围仅限于 if 语句中的括号。所以,当你以后做

return student;

if 块之外和定义另一个 student 变量的地方之外,该变量不再在范围内,因此在范围内的唯一 student 变量是James 一个。

这是一个注释版本:

(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"?

它是 if 语句的块作用域。但是,当您执行 return 时,它位于该块之外,因此无法再访问 Ken 学生变量,因此范围内的唯一变量是 James 变量。

Also, shouldn't there be an error as I'm redeclaring the same variable name 'student'?

定义一个已经在更高范围内定义的变量不是错误。相反,新声明隐藏或隐藏该范围内的其他声明,暂时覆盖该范围内的它。

letconstvar 不同,它在块语句内创建局部作用域。您没有收到错误,因为新变量 阴影 范围外的那个。