【问题标题】:Unhoisted variables (let, const) used in immediately invoked async function before declaration of said variables在声明所述变量之前立即调用的异步函数中使用的未提升变量(let,const)
【发布时间】:2020-05-31 00:14:48
【问题描述】:

下面的代码应该工作吗?

(async () => {
  await new Promise(r => setTimeout(r, 1000))
  useNum();
})();

let num = 10;
function useNum() {
  return num + 1;
}

https://jsbin.com/tayotitepa/edit?html,output

iOS 上的 Safari (v13.3) 说这是不可能的(num 变量不存在),而 Chrome 和 Firefox 认为这很好。

如果您删除 await new Promise... 行,Chrome 和 Firefox 就会抱怨。

Chrome 和 Firefox 似乎在这里是正确的,因为我们不是 awaiting 立即调用的异步函数,所以当 await new Promise... 行完成时,脚本的其余部分已经完成处理。但我想我会检查一下,因为也许规范说它严格关于变量声明的 ordering 和这些变量的用法,所以它的“时间”无关紧要变量的使用。

【问题讨论】:

  • 我认为这个问题与async/await 无关。 Safari 是错误的。
  • 另外,letconst 被提升;它的工作方式与var 提升不同。
  • 在 High Sierra 的 Safari 上运行良好

标签: javascript safari async-await hoisting


【解决方案1】:

我尝试了不同的场景,我观察到的是

  1. async/await 与此无关。
  2. let num 已提升,但值为 undefined

所以代码看起来像什么

let num; // --- hoisted with value as undefined
setTimeout(() => {}, 1000)
console.log(useNum());

num = 10; // --- value is assigned here
function useNum(str) {
  return num + 1;
}

如您所知,java-script 是同步的,即它每次执行每一行 a,所以当我们调用 useNum 方法时,num 将是未定义的。

【讨论】:

  • 您的代码与 OP 不同。应该是setTimeout(() => {console.log(useNum()}, 1000)
猜你喜欢
  • 1970-01-01
  • 2021-08-09
  • 2015-08-09
  • 2019-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多