Javascript 让变量作用域

Javascript 让变量作用域,javascript,variables,let,Javascript,Variables,Let,下面的代码将输出“1”。但是,关键字“let”不应该使x成为全局变量,从而使它对das()不可见吗?let应该将变量的作用域限制在它们声明的块上,但是在这里,我看到一个内部函数可以访问一个“let”变量,即使x声明在它的作用域之外。这怎么可能 函数测试(){ 函数das(){ 控制台日志(x); //此函数如何访问在其作用域之外声明的let变量? } 设x=1; das(); } letTest()let将变量的范围限制到当前块(在这种情况下,与letTest函数相同) das函数在该范围内声

下面的代码将输出“1”。但是,关键字“let”不应该使x成为全局变量,从而使它对das()不可见吗?let应该将变量的作用域限制在它们声明的块上,但是在这里,我看到一个内部函数可以访问一个“let”变量,即使x声明在它的作用域之外。这怎么可能

函数测试(){
函数das(){
控制台日志(x);
//此函数如何访问在其作用域之外声明的let变量?
}
设x=1;
das();
}

letTest()
let
将变量的范围限制到当前块(在这种情况下,与
letTest
函数相同)


das
函数在该范围内声明,因此它可以访问该范围内的任何内容(包括
x
)。

下面是一种思考
工作的方法:

  • 开始,让
  • 在相同的嵌套级别,通过源代码进行备份/备份,找到第一个
    {
  • 现在,让我们从
    中找到相应的
    }
  • 这为您提供了变量可见的范围。如果函数定义出现在该范围内,则为罚款;该变量对该函数中的代码可见

    现在,有点奇怪的是,在您的示例中,变量看起来像是在声明之前在作用域中使用的。这就是引用出现在声明之前这一事实变得更加有趣的地方


    通常,如果作用域中的代码在
    let
    实际发生之前引用了
    let
    声明的变量,则这是一个错误。然而,这是运行时的事情,而不是语法的事情。在您的情况下,在运行时,调用嵌套函数时,
    let
    将“发生”。

    问题是您没有改变x的值,在您的情况下,您只是将其记录到控制台,并且它们都嵌套在一个范围内,不限制内部函数,因此您的结果是预期的

    如果你做了这样的事

    function letTest() {
        function das () {
            console.log(x);
    // How does this function have access to a let variable declared outside its scope?
        }
        let x = 1;
        function change(){
           x = x + 1;
        }
    
        change();
    }
    letTest();
    
    现在您正试图更改x的值,编译器会抱怨

    如本文所述:它提供块范围内的访问。由于您的
    das()
    执行和x声明在同一块范围内,它将具有访问权限

    下面的开关示例是一个很好的例子,在案例1中使用
    var x='x'
    将导致它附加到函数范围,并可在console.log()中访问,但当尝试引用bar变量进行日志记录时,它会引发引用异常。但在默认情况下仍然有效

    const example = (foo) => {
        switch(foo) {
            case 0:
                break;
            case 1:
                let bar = 'bar';
                var x = 'x';
                break;
            default:
                console.log(bar);
                break;
        }
    
        console.log(x);
        console.log(bar);
    }
    
    example(1);
    

    函数在与
    x
    相同的块中声明,因此函数中的代码可以访问
    x

    如果您不想这样做,则始终可以添加新块:

    函数测试(){
    函数das(){
    console.log(x);//引用错误
    }
    {//新区块
    设x=1;
    das();
    }
    }
    letTest()@GTS-Joe

    let x
    letTest()
    上下文的本地变量,因此
    das()
    只是访问其
    x
    变量。那里没有发生什么奇怪的事。所以,“不”——它并没有变得全球化

    无论变量调用的上下文嵌套得有多深,总会有一个查找JS原则,它将遵循失败的查找,并在全局范围内继续查找此变量名称,只有到那时,当什么都没有找到时,它才会导致引用错误


    而这仅仅是因为JS原则下没有任何外观,所以所谓的
    闭包是可能的。

    它不在范围之外
    x
    das()
    在同一块范围内定义。该块中的任何其他内容都可以访问
    x
    。它包括任何嵌套函数、
    for
    循环、
    while
    循环和
    if
    条件。这包括
    elseif
    else
    ,它们在
    if
    条件中。

    我认为这是因为
    das
    x
    中定义的块中。。仅在2个块内,但其中一个块也围绕着
    let
    ,因此
    x
    不必是全局的,以便在嵌套函数中可见;它必须在局部范围内或某些外部范围内。
    let
    声明不局限于局部范围的可见性;它是本地作用域加上任何嵌套作用域。换句话说,嵌套函数中的代码是包含
    let
    的块的一部分。也许我错了,但我认为这与提升无关。所以“let”限制外部作用域,而不是内部作用域?@GTSJoe我刚刚对另一个答案发表了评论。没有“内部作用域”这样的东西。@GTSJoe换句话说,嵌套函数体的
    {}
    与作用域中出现的
    {}
    循环的
    {}
    没有区别。@GTSJoe还可以看到我的更新;我意识到我在使用
    let
    时忽略了一些细微差别。