Cer*_*nce 30 javascript specifications language-design async-await es2017
我尝试使用/不同的关键字和运算符时如何解释,发现以下语法完全合法:
// awaiting something that isn't a Promise is fine, it's just strange to do:
const foo = await /barbaz/
myFn()Run Code Online (Sandbox Code Playgroud)
错误:
未捕获的ReferenceError:未定义等待
看起来它尝试将解析await为变量名 ..?我期待
等待仅在异步功能中有效
或类似的东西
意外的令牌等待
令我恐惧的是,您甚至可以为其分配以下内容:
const await = 'Wait, this actually works?';
console.log(await);Run Code Online (Sandbox Code Playgroud)
如若不是如此明显的错误原因语法错误,因为它确实有let,finally,break,等?为什么允许这样做?第一个代码片段到底发生了什么?
Cer*_*nce 59
保留的关键字不能用作标识符(变量名)。与大多数其他特殊的Javascript的话(像那些在这个问题列出let,finally...),await是不是一个保留关键字,所以使用它作为一个变量名不抛出一个SyntaxError。当新语法出现时,为什么不将其变成保留关键字?
早在2011年,当ES5还是一个相对较新的事物时,使用await(和async)作为变量名的代码是完全有效的,因此您可能在几个站点上看到了类似的东西:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
Run Code Online (Sandbox Code Playgroud)
该变量名的选择可能看起来很奇怪,但没有任何问题。await并且async从来没有保留关键字-如果将ES2017规范的编写者设置await为保留关键字,并且浏览器实现了该更改,则在较新的浏览器上访问那些较旧网站的人将无法使用这些网站;他们可能会被打破。
因此,也许如果将它们变成保留关键字,那么一些选择了特殊变量名称的站点将无法正常工作-为什么这些站点的存在会永久性地影响ECMAscript的未来发展并导致代码混乱,如问题所在?
因为浏览器将拒绝实施破坏现有站点的功能。如果用户发现某个网站不能在一个浏览器上运行,而是在另一个浏览器上工作,则将激励他们切换浏览器-第一个浏览器的制造商不希望这样做,因为这将意味着它们的市场份额较小,即使它的功能使语言更加一致和易于理解。另外,规范的编辑者不希望添加一些永远不会实现的内容(或只会偶尔实现),因为那样的话,规范将失去其作为标准的地位-与其主要目标相反。
你可以看到这些相互作用在用行动Array.prototype.flatten和Array.prototype.contains-当浏览器开始出货他们,发现他们分手,由于名称冲突的几个现有的网站,所以浏览器实施的退了出去,和规格不得不进行调整(方法被重命名为.flat和.includes)。
实际上有是其中的情况await不能被用作标识符,这是ES6模块内:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
Run Code Online (Sandbox Code Playgroud)
这是因为在确定ES6(ES2015)模块的同时,async/ await已经面世(/ 提案的初始提交asyncawait可以在2014年初看到),因此在设计模块时,await可以在准备模块时将其作为保留关键字。面向未来,而不会破坏任何现有站点。
关于问题的第一个片段:
<script type="module">
const await = 'Does it work?';
</script>Run Code Online (Sandbox Code Playgroud)
这在语法上是有效的,因为它await是async函数之外的有效变量名,并且解释器认为您正在尝试除法,而不是使用正则表达式:
const foo = await / barbaz / myFn()
Run Code Online (Sandbox Code Playgroud)
不依赖自动分号插入会更早地发现问题,因为最后一个/不能解释为除法:
const foo = await /barbaz/
myFn()Run Code Online (Sandbox Code Playgroud)
这种精确的有些暧昧的情况实际上是专门在长大TC39会议上async/ await:
杨:您担心什么?
WH:代码序列中以await /开头的歧义,然后以不同的方式进行解释(由于await-as-identifier与await-as-operator的区别,这会在覆盖语法vs.之间引起翻转(在除法和开始一个正则表达式之间)。真正的语法。这是一个潜在的错误农场。
| 归档时间: |
|
| 查看次数: |
2960 次 |
| 最近记录: |