首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ES6立即调用箭头函数

ES6立即调用箭头函数
EN

Stack Overflow用户
提问于 2016-01-04 18:53:00
回答 3查看 85.4K关注 0票数 176

为什么这在Node.js控制台(在4.1.1和5.3.0中测试)可以工作,但在浏览器(在Chrome中测试)不能工作?

此代码块应创建并调用一个记录Ok的匿名函数。

代码语言:javascript
复制
() => {
  console.log('Ok');
}()

此外,尽管上面的可以在Node.js中运行,但它不能运行:

代码语言:javascript
复制
n => {
  console.log('Ok');
}()

也不是这样:

代码语言:javascript
复制
(n) => {
  console.log('Ok');
}()

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

EN

回答 3

Stack Overflow用户

发布于 2016-01-04 18:53:57

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

代码语言:javascript
复制
(() => {
  console.log('Ok');
})()

等同于IIFE

代码语言:javascript
复制
(function(){
   console.log('Ok')
})();

这在Node.js中有效而在Chrome中不起作用的可能原因是它的解析器将其解释为一个自动执行的函数,如下所示

代码语言:javascript
复制
function() { console.log('hello'); }();

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

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

对于参数化版本的,这将会起作用。

代码语言:javascript
复制
((n) => {
  console.log('Ok');
})()
票数 233
EN

Stack Overflow用户

发布于 2016-07-15 17:02:10

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

代码语言:javascript
复制
> 3 + 2
< 5

在这里,它的执行方式就好像它是一个表达式,但是您编写它的时候就好像它是一条语句。在正常的脚本中,值将被丢弃,但在这里,代码必须在内部损坏(就像用函数上下文和return语句包装整个语句一样),这会导致各种奇怪的效果,包括您遇到的问题。

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

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

代码语言:javascript
复制
{ let a = 3 }

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

代码语言:javascript
复制
({ let a = 3 })

那么它为什么要这样做呢?

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

控制台确实试图通过智能处理代码来修复这些边缘情况,但我认为这超出了本答案的范围。你可以提交一个bug,看看他们是否会考虑修复。

这里有一个非常类似的很好的例子:

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

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

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

票数 2
EN

Stack Overflow用户

发布于 2020-06-12 23:45:38

我问了一个这样的问题:

@getify我有一个问题:为了产生一个# declaration,我们在函数声明周围使用parans将其转换为函数表达式,然后调用它。现在在箭头函数IIFE中,我们为什么需要参数?!默认情况下箭头函数不是已经是一个表达式了吗?!

这是凯尔·辛普森的回答:

一个箭头函数是一个表达式,但是我们需要用括号b/c括起“操作符优先级”(sorta),以便调用箭头生命周期的最后一个括号应用于整个函数,而不仅仅是它主体的最后一个标记。

代码语言:javascript
复制
x => console.log(x)(4)    // trouble

vs

代码语言:javascript
复制
(x => console.log(x))(4)    // working

- getify (@getify) June 12, 2020

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34589488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档