[英]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);
如此明显的错误不应该导致语法错误,就像let
、 finally
、 break
等一样吗? 为什么允许这样做,第一个片段中到底发生了什么?
保留关键字不能用作标识符(变量名) 。 与大多数其他特殊 Javascript 词(如问题中列出的那些, let
、 finally
、...)不同, await
不是保留关键字,因此将它用作变量名不会引发 SyntaxError。 为什么新语法出来的时候没有把它做成保留关键字呢?
回到 2011 年,当 ES5 还是一个相对较新的东西时,使用await
(和async
)作为变量名的代码是完全有效的,所以你可能在几个网站上看到过这样的东西:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
该变量名称的选择可能看起来很奇怪,但它没有任何问题。 await
和async
从来都不是保留关键字——如果 ES2017 规范的作者将await
变成保留关键字,并且浏览器实现了这一更改,那么在较新浏览器上访问这些旧站点的人将无法使用这些站点; 他们可能会被打破。
因此,也许如果将它们制成保留关键字,那么一些选择特殊变量名的站点将无法正常工作——为什么这些站点的存在会永久影响 ECMAscript 的未来发展并导致像问题中那样混乱的代码?
因为浏览器将拒绝实现破坏现有站点的功能。 如果一个用户发现一个网站不能在一个浏览器上工作,但在另一个浏览器上工作,这将激励他们切换浏览器——第一个浏览器的制造商不会希望这样,因为这意味着他们的市场份额会减少,即使这是一种使语言更加一致和易于理解的功能。 此外,规范的编辑者不想添加永远不会实施(或只会偶尔实施)的内容,因为那样规范将失去其作为标准的某些地位——这与其主要目标背道而驰。
你可以看到这些与Array.prototype.flatten
和Array.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()
这在语法上是有效的,因为await
是async
函数之外的有效变量名,并且解释器认为您正在尝试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.