当前位置: 首页 > 知识库问答 >
问题:

为什么在函数内部使用let声明的一些变量在另一个函数中可用,而其他变量却导致引用错误?

程和蔼
2023-03-14

我不明白为什么变量在函数内部声明时会表现得如此奇怪。

>

  • first函数中,我使用let声明值为10的变量bc

    b = c = 10;
    

    second函数中显示:

    b + ", " + c
    

    这表明:

    10, 10
    

    同样在first函数中,我声明了值为10的A:

    let a = b = c = 10;
    

    但在second函数中显示错误:

    找不到变量:A

    现在,在first函数中,我声明值为20的d:

    var d = 20;
    

    但在second函数中,它显示了与前面相同的错误,但使用了变量d:

    找不到变量:D

    示例:

    null

    function first() {
      let a = b = c = 10;
      var d = 20;
      second();
    }
    
    function second() {
      console.log(b + ", " + c); //shows "10, 10"
    
      try{ console.log(a); }  // Rreference error
      catch(e){ console.error(e.message) }
    
      try{ console.log(d); } // Reference error
      catch(e){ console.error(e.message) }
    }
    first()

    null

  • 共有2个答案

    鲁涵映
    2023-03-14

    在函数first()中,变量bc是动态创建的,而不使用varlet

    let a = b = c = 10; // b and c are created on the fly
    

    不同于

    let a = 10, b = 10, c = 10; // b and c are created using let (note the ,)
    

    它们变成了隐含的全局。这就是它们在second()中可用的原因

    来自文档

    为未声明的变量赋值,在执行赋值时隐式地将其创建为全局变量(它成为全局对象的属性)。

    为了避免这种情况,可以使用“use strict”在使用未声明的变量时提供错误

    null

    "use strict"; // <-------------- check this
    
    function first() {
       /*
        * With "use strict" c is not defined.
        * (Neither is b, but since the line will be executed from right to left,
        * the variable c will cause the error and the script will stop)
        * Without, b and c become globals, and then are accessible in other functions
        */
       let a = b = c = 10;
       var d = 20;
       second();
    }
    
    function second() {
       console.log(b + ", " + c); //reference error
       console.log(a); //reference error
       console.log(d); //reference error
    }
    
    first();
    何升
    2023-03-14

    因为你实际上是在说:

    c = 10;
    b = c;
    let a = b;
    

    而不是你认为你在说什么,那就是:

    let a = 10;
    let b = 10;
    let c = 10;
    

    您会注意到,无论向链中添加多少变量,都只有第一个变量(a)会导致错误。

    这是因为“let”将变量的范围限定在声明它的块(或者,“local”,或多或少的意思是“在括号中”)。

    如果您声明了一个不带“let”的变量,那么它将全局地影响该变量的作用域。

    所以,在你设置变量的函数中,所有的东西都得到值10(如果你放一个断点,你可以在调试器中看到这一点)。如果在第一个函数中放入a、b、c控制台日志,那么一切都很好。

    但是当您离开该函数时,第一个(a)--记住,从技术上讲,按照赋值顺序,它是最后一个--“消失”了(同样,如果您在第二个函数中设置了断点,您可以在调试器中看到这一点),但是其他两个(或者您添加了多少个)仍然可用。

    这是因为,“let”仅适用于(因此仅适用于局部范围)链中的第一个变量--也是技术上最后一个被声明和赋值的变量。其余的技术上没有“让”在他们的前面。所以它们在技术上是全局声明的(即在全局对象上),这就是它们出现在第二个函数中的原因。

    试试吧:去掉“让”关键字。你所有的变量现在都可用了。

    “var”具有类似的局部作用域效果,但在变量如何“提升”方面有所不同,这是您应该明确理解的,但与您的问题没有直接关系。

    (顺便说一句,这个问题会有足够多的专业JS开发人员让它成为一个好的问题)。

    强烈建议您花点时间研究一下在JS中如何声明变量的差异:不使用关键字、使用“let”和使用“var”。

     类似资料:
    • 问题内容: 如果我有这个: 我之前已定义,因此效果很好。 我的问题是在第6行中调用。我试图用相同的定义在第一个函数之外进行定义,但是即使调用,它也始终相同。 我希望每次调用第一个函数然后再调用第二个函数时,都具有一个不同的。 我能做到这一点,而不界定外? 问题答案: 是的,您应该考虑在一个类中定义您的函数,并使word成为成员。这比较干净 创建类后,您必须将其实例化为对象并访问成员函数。 另一种方

    • 问题内容: 我从很多地方都听说过,全局变量本来就是讨厌和邪恶的,但是当使用一些非面向对象的Javascript时,我看不到如何避免它们。说我有一个函数,它使用复杂的算法使用随机数和填充物来生成数字,但是我需要在其他函数(回调或其他函数)中继续使用该特定数,因此不能成为同一函数的一部分。 如果最初生成的数字是局部变量,则无法从那里访问它。如果函数是对象方法,我可以将数字设为属性,但是它们不是属性,并

    • 问题内容: 我刚刚开始自学Python,此脚本需要一些帮助: 我想得到它。 问题答案: 你快到了。您正在尝试修改全局变量,因此必须添加以下语句: 如果运行以下版本,则会看到您的版本中发生了什么: 输出: 运行它的方法,最终尝试在中修改函数的局部变量,这基本上是未定义的行为。请参阅文档中的警告: 注意: 默认 本地语言的 行为如以下功能所述:不应尝试对默认 本地 字典进行修改。如果需要在函数返回后查

    • 问题内容: 我正在尝试了解Python的可变范围方法。在此示例中,为什么f()能够更改的值(x如在其中看到的)main(),但不能更改的值n? 输出: 问题答案: 一些答案在函数调用的上下文中包含单词“ copy”。我感到困惑。 Python不复制对象的函数调用中传递过。 功能参数是名称。调用函数时,Python会将这些参数绑定到您传递的任何对象上(通过调用方作用域中的名称)。 对象可以是可变的(

    • 我定义了一个名为marger的函数来查找两个参数(num1、num2)之间的较大数。现在,我想在另一个名为“最大”的函数中使用这个函数,这个函数获得一个数组并返回该数组的最大个数,但我被卡住了。有人能帮我吗?下面是我的代码:

    • 问题内容: 我究竟做错了什么?为什么$ path在函数外部正确打印,但是在函数内部无法访问? 问题答案: 因为它没有在函数中定义。 有几种方法可以解决此问题: 1)使用亚历克斯所说的话,告诉函数它是一个全局变量: 2)将其定义为常量: 3)如果特定于该函数,则将其传递给该函数: 根据功能的实际工作原理,其中之一会起作用。