【问题标题】:Despite ES6, are there instances when var is the most appropriate keyword to use?尽管有 ES6,但是否存在 var 是最合适的关键字的情况?
【发布时间】:2018-05-03 05:16:49
【问题描述】:

我会尽量让这个简洁...

随着 ES6 的大肆宣传,我觉得使用 var 关键字越来越受到整个 JS 社区的反对。由于这种(公认的)普遍共识,我已经养成了避免使用var 代替较新的const 和let 关键字来创建变量的习惯。

下面是我编写的一段代码示例,其中我无法使用const,因为我想重新定义一个变量。我也在使用async / await,所以所有代码都在同一个block-level scope 中,这显然也阻止了你重新定义let 变量。所以我唯一的选择是使用var(或创建另一个let 变量)。

这是代码。通过 Mongoose 将新用户帐户保存到 MongoDB...

router.post('/signup', async (req, res, next) => {
  const { email, password } = req.body;

  const user = await userModel.findOne({ email });
  if (user) { res.send('Email already in use.'); return; }

  // here is where the issue occurs - use var instead?
  let newUser = new userModel({ email, password });
  let newUser = await newUser.save();

  console.log(newUser); // just checking everything works

  res.send({ message: 'New user account created!' });
});

MDN 提到了这种行为......只有一句话!那没有帮助。 :( 然后他们继续讨论提升行为,这不是我的问题,或者至少我不明白这有什么关系。MDN Source Here。

总之……

  • 这是var 是最适合使用的关键字的例子吗?

  • 1234563 , 8 等)?

免责声明:我知道我并不绝对需要保存这些变量,但在我看来,编写稍微冗长的代码但也更易于阅读和理解是值得的。我可以使用 var,尽管这是一个有趣的案例。

【问题讨论】:

  • 为什么这个代码块需要重新定义一个变量?我没看到。您可以“分配”给使用let 定义的变量就好了。我不知道var 比选择合适的let 或const 更好。
  • 不,没有任何一种情况应该使用var 而不是let 或const。您可以重新分配使用 let 关键字定义的变量,方法与使用 var 定义的变量相同。并且永远没有任何充分的理由在同一范围内重新定义同一变量(不要阅读重新分配)。

标签: javascript ecmascript-6 async-await syntax-error


【解决方案1】:

没有理由在 ES6 中使用 var。 const 应该是您的默认设置。使用let 而不是const 的唯一原因是您想稍后在同一块中重新分配变量。在这种情况下,您无需再次声明它,只需为其分配新值即可:

let newUser = new userModel({ email, password });
newUser = await newUser.save();
// allowed to reassign because `newUser` is not `const`

根据 save 所做的事情,我怀疑您可以这样做:

const newUser = new userModel({ email, password });
await newUser.save();

newUser.save(); 应该拒绝它在保存失败时返回的 Promise,这 await 将转换为抛出的错误。所以在await之后的代码中保存是否成功应该是毫无疑问的。如果到达这些行,则保存成功。

【讨论】:

  • 没有理由在 JavaScript 中使用 var,但 let 可能是我们的默认值。 ;)
  • 天哪——我太笨了。当然,这完全有道理。谢谢!几乎每个人都有很好的答案。
  • @Paleo let 不是一个好的默认值。当您阅读const newUser = new userModel({ email, password }); 时,它会准确地告诉您newUser 对块的其余部分指的是什么,而无需任何进一步的扫描。 let newUser = new userModel({ email, password }); 告诉您 newUser 可能 用于块的其余部分,但您需要扫描整个块才能确定。默认为const 可以更轻松、更快速地阅读和编写更好的代码。
  • 如果可能,一般应避免重新分配,而是应创建一个新变量(出于上述原因)。在许多情况下这是不可能的,使用let 表示变量不会立即初始化为其最终值。通常这意味着它是某种计算 EG 的变量。 count, sum, product 迭代器 i,j,k 或最终值未确定的变量,直到稍后有更多信息可用(可能是在某个回调函数内部或内部分配的变量switch 语句的情况)。
  • const 应该是您的默认值...多么误导...一个无法更改的 variable。
【解决方案2】:

这不是使用let、var 或const 的问题。
在同一个作用域内,一个变量名不能被多次声明,否则会报如下错误; SyntaxError: Identifier 'newUser' has already been declared
您可以声明一次,然后根据需要分配值。
let newUser = new userModel({ email, password }); newUser = await newUser.save();

【讨论】:

    【解决方案3】:

    var 的使用通常在 linter 规则中受到限制,因为它很容易在 ES6 中被滥用。这不是var 的有效案例。正如另一个答案所提到的,应该重新分配变量,而不是重新声明:

      let newUser = new userModel({ email, password });
      newUser = await newUser.save();
    

    var 在 ES6 中唯一有效的情况是在顶级作用域中定义一个全局:

    <script>var FOO = 1;</script>
    

    如果由于某种原因多次定义变量,let 和 const 将导致 Identifier has already been declared 错误:

    <script>let FOO = 1;</script>
    ...
    <script>let FOO = 1;</script>
    

    并且if (typeof FOO === 'undefined) 保护不适用,因为它创建了块范围。

    这仅适用于浏览器脚本。 Node.js 脚本在模块范围内进行评估。

    替代方案可能涉及引用 this(松散模式)或 window 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 2017-01-01
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      相关资源
      最近更新 更多