为什么等待和异步有效变量名称?

问题描述 投票:18回答:1

我正在尝试在不同的关键字和运算符周围解释/的方式,并发现以下语法完全合法:

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

错误:

未捕获的ReferenceError:未定义await

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

await仅在异步函数中有效

或者类似的东西

意外的令牌等待

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

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

不应该这么明显错误导致语法错误,就像letfinallybreak等一样吗?为什么允许这样做,以及在第一个片段中发生了什么?

javascript async-await specifications language-design es2017
1个回答
49
投票

保留的关键字不能用作identifiers (variable names)。与大多数其他特殊Javascript单词(如问题中列出的单词,letfinally,...)不同,await不是保留关键字,因此将其用作变量名称不会抛出SyntaxError。当新语法出现时,为什么不将它变成保留关键字?

Backwards compatibility

早在2011年,当ES5仍然是一个相对较新的东西时,使用await(和async)作为变量名的代码是完全有效的,所以你可能在几个网站上看到过这样的东西:

function timeout(ms) {
  var await = $.Deferred();
  setTimeout(await.resolve, ms);
  return await.promise();
};

变量名称的选择可能看起来很奇怪,但它没有任何问题。 awaitasync从未被保留过关键字 - 如果ES2017规范的编写者将await变成保留关键字,并且浏览器实现了这种变化,那么在新浏览器上访问那些旧网站的人将无法使用这些网站;他们可能会被打破。

因此,如果它们被制作成保留关键字,一些选择特殊变量名称的网站将无法正常工作 - 为什么这些网站的存在会永久影响ECMAscript的未来发展并导致像问题一样令人困惑的代码?

因为浏览器会拒绝实现破坏现有网站的功能。如果用户发现一个站点不能在一个浏览器上工作,但在另一个浏览器上工作,那将激励他们切换浏览器 - 第一个浏览器的制造商就不会想要这个,因为这意味着他们的市场份额会减少,即使它是一种使语言更加一致和易懂的功能。此外,规范的编辑不希望添加一些永远不会实现的东西(或者只会偶尔实现),因为规范会失去一些标准 - 与其主要目标相反。

您可以看到这些与Array.prototype.flattenArray.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可以成为保留关键字以准备未来,不破坏任何现有网站。


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

const foo = await /barbaz/
myFn()

这在语法上是有效的,因为awaitasync函数之外的有效变量名,并且解释器认为你试图划分,而不是使用正则表达式:

const foo = await / barbaz / myFn()

不依赖于自动分号插入会更早地识别出问题,因为最后的/不能被解释为除法:

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

这个确实有些含糊不清的情况实际上是在TC39 meeting / asyncawait中提出的:

YK:你有什么担心的?

WH:以await /开头的代码序列的模糊性,然后以不同的方式进行解释(由于await-as-identifier与await-as-operator的区别,在翻译之间翻转/启动正则表达式)由封面语法与真实的语法。这是一个潜在的错误农场。

© www.soinside.com 2019 - 2024. All rights reserved.