编程语言
首页 > 编程语言> > javascript – 为什么等待和异步有效变量名称?

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.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()

这在语法上是有效的,因为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