首页 > 解决方案 > 最后的行(尚未执行)如何影响代码的开头?为什么它会抛出不正确的错误?

问题描述

所以我的x is not defined代码中有一个错误,这让我有点困惑,因为x之前已经定义了几行。我不得不花一些时间调整我的代码,删除和添加行,直到我设法理解它发生的原因。删除所有不必要的信息后,现在代码如下所示:

let foo = 2;
console.log(foo);

if (foo === 2){
    console.log(foo);
    let foo = 1;
}

foo is not defined在第 5 行抛出。当我尝试时会弹出一个错误console.log(foo)!如果我删除第 6 行let foo = 1;,则代码可以正常工作。我的意思是在我第二次声明之前发生了错误foo。所以第一个问题是:

  1. 第 6 行(尚未执行)怎么可能导致第 5 行出错?

我不明白的第二件事是为什么它说foo is not defined而不是foo has been already declared. let如果我用var错误替换第二个将出现在第 6 行,它会说它foo has been already declared看起来很好。但是let被设置为第二个标识符总是会引发不正确的错误。

  1. 为什么会抛出不正确的错误?

在测试了不同的场景后,我注意到结果取决于我使用的标识符:

identifiers |            result
----------------------------------------------
  var var   |      the code works well
  var let   |       not defined error
  let var   | has been already declared error
  let let   |       not defined error

所以第三个问题是:

  1. 为什么每个人都反对var在这种情况下使用双重使用var是代码完美运行的唯一方法?是例外吗?

标签: javascriptnode.jssyntax-erroridentifierreferenceerror

解决方案


When you declare a variable using let it is valid within the scope of the current code block. Your second let foo declaration defines a separate foo than the first variable and it's only valid within the if-block. However you are using it before it is defined so you get the error correctly that it's not defined yet.

If you truly intend there to be two different foo variables, I'd recommend calling them something else (foo1 and foo2 for example) to avoid the conflict. Then it becomes clear that you are using the variable before it's defined.

let foo1 = 2;
console.log(foo1);

if (foo1 === 2){
    console.log(foo1);
    let foo2 = 1;
}

If you mean for line 5 to be using the first instance of foo set to 2, then you've hidden it by the new definition happening within the if-block of code.

If you mean for the foo that's set to 1 to be used on line 5 then you should move its definition to before its use.

Note that using var has a different result because the scope of var variables his broader than the scope of let variables. See here which has this definition:

let allows you to declare variables that are limited to a scope of a block statement, or expression on which it is used, unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.

To try to make it more clear I've marked your code up with the state of the variables at each stage of the code:

let foo = 2;          // foo defined and set to 2
console.log(foo);     // foo defined and set to 2

if (foo === 2)        // foo defined and set to 2
{                     // <-- start of the if-block!
    console.log(foo); // foo not defined yet
    let foo = 1;      // foo defined and set to 1
}                     // <-- end of if-block!
console.log(foo);     // foo defined and set to 2

推荐阅读