ES6立即调用箭头功能

JavaScript Node.js

小小Stafan宝儿

2020-04-03

为什么这在Node.js控制台(在4.1.1和5.3.0中进行了测试)中不能运行,而在浏览器中(在Chrome中进行了测试)中却不起作用?该代码块应创建并调用一个记录日志的匿名函数Ok

() => {
  console.log('Ok');
}()

此外,虽然上述作品中的节点,这并不工作:

n => {
  console.log('Ok');
}()

也没有:

(n) => {
  console.log('Ok');
}()

奇怪的是,当添加参数时,它实际上会SyntaxError在立即调用的部分抛出a

第4020篇《ES6立即调用箭头功能》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

2个回答
古一 2020.04.03

之所以会出现这样的问题,是因为控制台本身试图模仿您当前定位的上下文的全局范围。它还尝试捕获您在控制台中编写的语句和表达式的返回值,以便将其显示为结果。举个例子:

> 3 + 2
< 5

在这里,它好像是一个表达式一样执行,但是您已经把它写成是一个语句。在普通脚本中,该值将被丢弃,但是在这里,必须对代码进行内部处理(例如,将整个语句包装在函数上下文和return语句中),这会导致各种奇怪的结果,包括您遇到的问题。

这也是脚本中的一些裸露ES6代码可以正常运行,但不能在Chrome Dev Tools控制台中运行的原因之一。

尝试在Node和Chrome控制台中执行此操作:

{ let a = 3 }

在Node或<script>标签中,它工作正常,但在控制台中,它给出Uncaught SyntaxError: Unexpected identifier它还为您提供了到源的链接VMxxx:1,您可以单击该链接的形式来检查评估的源,其显示为:

({ let a = 3 })

那么为什么要这样做呢?

答案是它需要将您的代码转换为表达式,以便将结果返回给调用方并显示在控制台中。您可以通过将语句包装在括号中来做到这一点,使其成为表达式,但也使上面的语句在语法上不正确(表达式不能具有语句块声明)。

控制台确实通过精通代码来尝试解决这些极端情况,但是我认为这超出了此答案的范围。您可以提交一个错误,看看是否可以解决这些问题。

这是一个非常相似的例子:

https://stackoverflow.com/a/28431346/46588

使代码正常工作的最安全方法是确保可以将其作为表达式运行,并检查SyntaxError源链接以查看实际的执行代码是什么,然后从中进行反向工程解决方案。通常,它是指一对放在战略上的括号。

简而言之:控制台试图尽可能准确地模拟全局执行上下文,但是由于与v8引擎和JavaScript语义的交互的局限性,有时难以解决或无法解决。

蛋蛋 2020.04.03

没有括号,所有这些都不起作用。

为什么?

因为根据规范:

  1. ArrowFunction列在AssignmentExpression
  2. CallExpressionLHS必须是MemberExpressionSuperCallCallExpression

因此,一个ArrowFunction不能在一个的LHS CallExpression


什么这实际上意味着在如何=>应解释是,它可以在同一水平排序为赋值运算符=+=等等。

含义

  • x => {foo}() 没有成为(x => {foo})()
  • 解释器尝试将其解释为 x => ({foo}())
  • 因此它仍然是一个SyntaxError
  • 因此,解释器确定(必须输入的错误,并引发SyntaxError

Babel也有一个关于的错误

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android