javascript – 为什么等待和异步有效变量名称?
作者:互联网
我正在尝试围绕不同的关键字和运算符解释如何/被解释,并发现以下语法是完全合法的:
// 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等一样吗?为什么允许这样做,以及在第一个片段中发生了什么?
解决方法:
保留关键字不能用作identifiers (variable names).与大多数其他特殊Javascript单词(如问题中列出的那些,最后,…)不同,await不是保留关键字,因此将其用作变量名称不会抛出SyntaxError .当新语法出现时,为什么不将它变成保留关键字?
向后兼容性
早在2011年,当ES5仍然是一个相对较新的东西时,使用等待(和异步)作为变量名称的代码是完全有效的,所以你可能在几个网站上看到过这样的东西:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
变量名称的选择可能看起来很奇怪,但它没有任何问题. await和async从未被保留过关键字 – 如果ES2017规范的编写者等待保留关键字,并且浏览器实现了这种改变,那么在新浏览器上访问那些旧网站的人将无法使用这些网站;他们可能会被打破.
因此,如果它们被制作成保留关键字,一些选择特殊变量名称的网站将无法正常工作 – 为什么这些网站的存在会永久影响ECMAscript的未来发展并导致像问题一样令人困惑的代码?
因为浏览器会拒绝实现破坏现有网站的功能.如果用户发现一个站点不能在一个浏览器上工作,但在另一个浏览器上工作,那将激励他们切换浏览器 – 第一个浏览器的制造商就不会想要这个,因为这意味着他们的市场份额会减少,即使它是一种使语言更加一致和易懂的功能.此外,规范的编辑不希望添加一些永远不会实现的东西(或者只会偶尔实现),因为规范会失去一些标准 – 与其主要目标相反.
您可以在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作为保留关键字来准备未来,不破坏任何现有网站.
关于问题中的第一个片段:
const foo = await /barbaz/
myFn()
这在语法上是有效的,因为await是异步函数之外的有效变量名,并且解释器认为你试图划分,而不是使用正则表达式:
const foo = await / barbaz / myFn()
不依赖于自动分号插入会更早地识别出问题,因为最后/不能被解释为除法:
const foo = await /barbaz/;
myFn();
这个确实有点模棱两可的情况实际上是在异步/等待的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,async-await,specifications,language-design,es2017 来源: https://codeday.me/bug/20190930/1836034.html