Javascript ES6 立即调用箭头函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34589488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:36:19  来源:igfitidea点击:

ES6 immediately invoked arrow function

javascriptnode.jsarrow-functions

提问by XCS

Why does this work in a Node.jsconsole (tested in 4.1.1 and 5.3.0) but doesn't work in the browser (tested in Chrome)? This code block should create and invoke an anonymous function that logs Ok.

为什么这在Node.js控制台中有效(在 4.1.1 和 5.3.0 中测试)但在浏览器中不起作用(在 Chrome 中测试)?此代码块应创建并调用一个匿名函数来记录Ok.

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

Also, while the above worksin Node, this does not work:

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

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

Nor this:

也不是这个:

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

What's odd is that when the parameter is added it actually throws a SyntaxErrorat the immediately-invoking part.

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

回答by void

You need to make it a function expressioninstead of function definitionwhich doesnt need a name and makes it a valid JavaScript.

您需要使其成为函数表达式而不是函数定义,后者不需要名称并使其成为有效的 JavaScript。

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

Is the equivalent of IIFE

相当于IIFE

(function(){
   console.log('Ok')
})();

And the possible reason why this works in Node.js but not in chrome is because its parser interprets it as a self executing function, as this

这在 Node.js 中有效但在 chrome 中无效的可能原因是它的解析器将其解释为自执行函数,因为

function() { console.log('hello'); }();

works fine in Node.jsThis is a function expression and chrome and firefox and most of the browser interprets it this way. You need to invoke it manually.

Node.js这是一个函数表达式和 chrome 和 firefox 中工作正常,大多数浏览器都以这种方式解释它。您需要手动调用它。

The most widely accepted way to tell the parser to expect a function expression is just to wrap it in parens, because in JavaScript, parens can't contain statements. At this point, when the parser encounters the function keyword, it knows to parse it as a function expression and not a function declaration.

告诉解析器期望函数表达式的最广泛接受的方法是将它包装在括号中,因为在 JavaScript 中,括号不能包含语句。此时,当解析器遇到 function 关键字时,它知道将其解析为函数表达式而不是函数声明。

Regarding the parametrized version, this will work.

关于参数化版本,这将起作用。

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

回答by Paul S.

None of these should work without parentheses.

这些都不应该在没有括号的情况下工作。

Why?

为什么?

Because according in the spec:

因为根据规范:

  1. ArrowFunctionis listed under AssignmentExpression
  2. The LHS of a CallExpressionmust be a MemberExpression, SuperCallor CallExpression
  1. ArrowFunction列在AssignmentExpression
  2. CallExpressionLHS必须是MemberExpressionSuperCallCallExpression

So an ArrowFunctioncannot be on the LHS of a CallExpression.

所以ArrowFunction不能在CallExpression的 LHS 上。



What this effectively means in how =>should be interpreted, is that it works on the same sort of level as assignment operators =, +=etc.

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

Meaning

意义

  • x => {foo}()doesn'tbecome (x => {foo})()
  • The interpreter tries to interpret it as x => ({foo}())
  • Thus it's still a SyntaxError
  • So the interpreter decides that the (must have been wrong and throws a SyntaxError
  • x => {foo}()不会变成(x => {foo})()
  • 解释器试图将其解释为 x => ({foo}())
  • 因此它仍然是一个SyntaxError
  • 所以解释器决定(一定是错误的并抛出一个SyntaxError


There was a bug on Babel about it here, too.

有关于它的通天塔中的错误在这里,太。

回答by Klemen Slavi?

The reason you're seeing problems like this is that the console itself tries to emulate the global scope of the context you're currently targeting. It also tries to capture return values from statements and expressions you write in the console, so that the show up as results. Take, for instance:

您看到此类问题的原因是控制台本身试图模拟您当前所针对的上下文的全局范围。它还尝试从您在控制台中编写的语句和表达式中捕获返回值,以便显示为结果。举个例子:

> 3 + 2
< 5

Here, it executes as though it were an expression, but you've written it as though it were a statement. In normal scripts, the value would be discarded, but here, the code must be internally mangled (like wrapping the entire statement with a function context and a returnstatement), which causes all sorts of weird effects, including the problems you're experiencing.

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

This is also one of the reasons why some bare ES6 code in scripts works fine but doesn't in Chrome Dev Tools console.

这也是为什么脚本中的一些裸 ES6 代码可以正常工作,但在 Chrome Dev Tools 控制台中却没有的原因之一。

Try executing this in Node and Chrome console:

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

{ let a = 3 }

In Node or a <script>tag it works just fine, but in the console, it gives Uncaught SyntaxError: Unexpected identifier. It also gives you a link to the source in the form of VMxxx:1which you can click to inspect the evaluated source, which shows up as:

在 Node 或<script>标签中它工作得很好,但在控制台中,它给出Uncaught SyntaxError: Unexpected identifier. 它还为您提供了一个指向源的链接VMxxx:1,您可以单击该链接来检查评估的源,该链接显示为:

({ let a = 3 })

So why did it do this?

那么它为什么这样做呢?

The answer is that it needs to convert your code into an expression so that the result can be returned to the caller and displayed in the console. You can do this by wrapping the statement in parentheses, which makes it an expression, but it also makes the block above syntactically incorrect (an expression cannot have a block declaration).

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

The console does try to fix these edge cases by being smart about the code, but that's beyond the scope of this answer, I think. You can file a bug to see if that's something they'd consider fixing.

控制台确实尝试通过对代码进行智能处理来解决这些边缘情况,但这超出了本答案的范围,我认为。您可以提交一个错误,看看这是否是他们考虑修复的问题。

Here's a good example of something very similar:

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

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

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

The safest way to make your code work is to make sure it can be run as an expression and inspect the SyntaxErrorsource link to see what the actual execution code is and reverse engineer a solution from that. Usually it means a pair of strategically placed parentheses.

使您的代码工作的最安全方法是确保它可以作为表达式运行并检查SyntaxError源链接以查看实际执行代码是什么,并从中逆向工程解决方案。通常它意味着一对战略性地放置的括号。

In short:the console tries to emulate the global execution context as accurately as possible, but due to the limitations of interaction with the v8 engine and JavaScript semantics this is sometimes hard or impossible to solve.

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