繁体   English   中英

为什么 await 和 async 是有效的变量名?

[英]Why are await and async valid variable names?

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

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

错误:

未捕获的 ReferenceError:等待未定义

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

await 只在 async 函数中有效

或者类似的东西

意外的令牌等待

令我恐惧的是,你甚至可以给它赋值:

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

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

保留关键字不能用作标识符(变量名) 与大多数其他特殊 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 的未来发展并导致像问题中那样混乱的代码?

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

你可以看到这些与Array.prototype.flattenArray.prototype.contains的交互——当浏览器开始发布它们时,发现它们由于名称冲突而破坏了一些现有站点,因此浏览器退出了实现,并且必须调整规范(方法重命名为.flat.includes )。


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

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

这是因为在设计 ES6 (ES2015) 模块时, async / await已经出现( async / await提案的初始提交可以在 2014 年初看到),因此在设计模块时,可以进行await为将来做准备的保留关键字,不会破坏任何现有站点。


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

 const foo = await /barbaz/ myFn()

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

const foo = await / barbaz / myFn()

不依赖自动分号插入会更早地发现问题,因为最后一个/不能被解释为除法:

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

这种有点模棱两可的情况实际上是在TC39 会议上关于async / await的专门提出的:

YK:你在担心什么?

WH:以 await/ 开头然后以不同方式解释的代码序列的歧义(由于 await-as-identifier 与 await-as-operator 的区别在除法和开始正则表达式之间翻转 / )通过覆盖语法 vs.真正的语法。 这是一个潜在的错误农场。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM