javascript - 为什么等待和异步有效的变量名?

标签 javascript async-await specifications language-design ecmascript-2017

我正在尝试如何 /当围绕不同的关键字和运算符进行解释时,发现以下语法完全合法:

// awaiting something that isn't a Promise is fine, it's just strange to do:
const foo = await /barbaz/
myFn()


错误:

Uncaught ReferenceError: await is not defined



看起来它试图解析 await作为变量名..?我期待

await is only valid in async function



或者类似的东西

Unexpected token await



令我恐惧的是,你甚至可以给它分配东西:

const await = 'Wait, this actually works?';
console.log(await);


如此明显的错误不应该像 let 那样导致语法错误吗? , finally , break , ETC?为什么允许这样做,以及第一个片段中到底发生了什么?

最佳答案

保留关键字不能用作 identifiers (variable names) 。与大多数其他特殊的 Javascript 单词(如问题中列出的 letfinally 、...)不同,await 不是保留关键字,因此将其用作变量名不会引发 SyntaxError。为什么新语法出来的时候不把它变成保留关键字?
向后兼容性
早在 2011 年,当 ES5 还是一个相对较新的东西时,使用 await (和 async )作为变量名的代码是完全有效的,所以你可能在几个网站上看到过这样的东西:

function timeout(ms) {
  var await = $.Deferred();
  setTimeout(await.resolve, ms);
  return await.promise();
};
该变量名称的选择可能看起来很奇怪,但它并没有错。 awaitasync 从来都不是保留关键字——如果 ES2017 规范的编写者将 await 设置为保留关键字,并且浏览器实现了该更改,那么在较新的浏览器上访问这些旧站点的人将无法使用这些站点;他们很可能会被打破。
因此,也许如果将它们设为保留关键字,一些选择特殊变量名的站点将无法正常工作 - 为什么这些站点的存在会永久影响 ECMAscript 的 future 发展并导致问题中的代码困惑?
因为浏览器将拒绝实现破坏现有网站的功能。 如果用户发现一个站点不能在一个浏览器上运行,但在另一个浏览器上运行,这将激励他们切换浏览器 - 第一个浏览器的制造商不会想要这样,因为这意味着他们的市场份额减少,甚至如果它是使语言更加一致和易于理解的功能。此外,规范的编辑者不想添加一些永远不会实现(或只会偶尔实现)的东西,因为那样规范将失去其作为标准的一些地位——与其主要目标相反。
您可以看到这些与 Array.prototype.flatten Array.prototype.contains 的交互作用——当浏览器开始发布它们时,发现它们由于名称冲突而破坏了一些现有站点,因此浏览器退出了实现,并且必须调整规范(这些方法被重命名为 .flat .includes )。

实际上有一种情况是 await 不能作为标识符,在 ES6 模块内部:

<script type="module">
  const await = 'Does it work?';
</script>

这是因为在设计 ES6 (ES2015) 模块时,async/await 已经出现(initial commit for the async / await proposal 可以在 2014 年初看到),因此在设计模块时,可以将 await 作为保留关键字,为 future ,而不会破坏任何现有网站。

关于问题中的第一个片段:

const foo = await /barbaz/
myFn()

这在语法上是有效的,因为 awaitasync 函数之外的有效变量名,并且解释器认为您正在尝试除法,而不是使用正则表达式:
const foo = await / barbaz / myFn()
不依赖自动分号插入会更早发现问题,因为最后一个 / 不能被解释为除法:

const foo = await /barbaz/;
myFn();

这种确切的有点模棱两可的情况实际上是在 async/await 上的 TC39 meeting 中特别提出的:

YK: What are you worried about?

WH: Ambiguities on code sequences that start with await/ and then get interpreted in diverging ways (due to the await-as-identifier vs await-as-operator distinction that flips the / between division and starting a regexp) by cover grammars vs. real grammars. It's a potential bug farm.

关于javascript - 为什么等待和异步有效的变量名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55934490/

相关文章:

c#.net 停止运行异步方法

html - 属性的 label 标签可以与普通的 div 相关联吗?

javascript - 如何循环遍历多个音频文件并使用 javascript 顺序播放它们?

Javascript,更改谷歌地图标记颜色

c# - AWS Lambda c# 异步 API 调用

c# - 如何编写 C# 5 异步?

pdf - 在哪里可以找到 XFA 规范或 DTD/架构?

javascript - ES2015函数名推断在哪里定义的?

javascript - 在 ThreeJS 中加载 *.obj 文件的模型着色错误

javascript - 我可以使用空字符串作为对象标识符吗?